Introduction
The Candy problem is a classic greedy algorithm interview question frequently asked by companies such as NPCI, Amazon, Google, and Microsoft.
The challenge is to distribute candies among children according to their ratings while minimizing the total number of candies distributed.
Although the problem appears straightforward, finding an optimal solution with O(n) time complexity and O(1) auxiliary space requires careful observation.
In this article, we'll explore the intuition, derive the optimal greedy approach, and implement it in Java.
Problem Statement
There are n children standing in a line.
Each child has a rating represented by:
arr[i]
You must distribute candies according to the following rules.
Rule 1
Every child must receive at least one candy.
Rule 2
If a child has a higher rating than an adjacent neighbor, they must receive more candies than that neighbor.
Return the minimum number of candies required.
Example 1
Input
arr = [1, 0, 2]
Distribution
Ratings : 1 0 2
Candies : 2 1 2
Total
2 + 1 + 2 = 5
Output
5
Example 2
Input
arr = [1, 2, 2]
Distribution
Ratings : 1 2 2
Candies : 1 2 1
Total
1 + 2 + 1 = 4
Output
4
Understanding the Problem
Consider:
Ratings:
1 2 3 4
Since ratings continuously increase:
Candies:
1 2 3 4
Total:
10
Now consider:
Ratings:
4 3 2 1
Candies must become:
4 3 2 1
Total:
10
The problem becomes interesting when both increasing and decreasing sequences appear together.
Brute Force Approach
One approach is repeatedly updating candy counts until all constraints are satisfied.
Example:
1 3 2 4
Keep adjusting candies until valid.
Complexity
O(n²)
This is too slow for:
n = 100000
Better Observation
Every rating pattern consists of:
Increasing slopes
Decreasing slopes
Flat regions
Example:
1 2 3 2 1
Visualization:
3
/ \
2 2
1 1
This forms a mountain.
If we can count candies contributed by increasing and decreasing slopes, we can solve the problem efficiently.
Two-Pass Solution
A common solution uses two arrays.
Left to Right
If the current rating is greater than the previous rating:
left[i] = left[i - 1] + 1;
Right to Left
If the current rating is greater than the next rating:
right[i] = right[i + 1] + 1;
Final Candy Count
max(left[i], right[i])
This works in:
Time : O(n)
Space : O(n)
But the expected solution requires:
Space : O(1)
Optimal Greedy Idea
Instead of storing arrays, we track:
up = length of increasing slope
down = length of decreasing slope
peak = longest increasing slope before descent
The idea:
Increasing ratings form an arithmetic progression.
Decreasing ratings form an arithmetic progression.
The peak should not be counted twice.
Visual Example
Ratings
1 2 3 2 1
Increasing Slope
1 2 3
Candies
1 + 2 + 3 = 6
Decreasing Slope
2 1
Candies
2 + 1 = 3
Total
9

Join the conversation! Your thoughts help the community grow.