There are n children standing in a line, each with a rating value. You are handing out candies under two rules:
Return the minimum total number of candies you must give out.
Input: ratings = [1,0,2] Output: 5 Give 2, 1, 2 candies to the three children respectively.
Input: ratings = [1,2,2] Output: 4 Give 1, 2, 1 candies. The last two children have equal ratings, so the third can get just one.
- n == ratings.length - 1 <= n <= 2 * 10^4 - 0 <= ratings[i] <= 2 * 10^4
Each child has two neighbors, and a single sweep can only respect one side. So make two passes: a left-to-right pass fixes every "higher than my left neighbor" rule, a right-to-left pass fixes every "higher than my right neighbor" rule, and taking the larger of the two requirements at each child satisfies both at once.
“Does every child get at least one candy?”
Yes — the minimum any child receives is one.
“What about equal adjacent ratings?”
No constraint — equal neighbors can get different candy counts, so each may stay at the minimum.
“Am I minimizing the total?”
Yes — satisfy the rules with the fewest candies overall.
Each child has a left and a right neighbor, so one pass can't handle both sides.
I'll do a left-to-right pass so anyone rated higher than their left neighbor gets one more than them.
Then a right-to-left pass does the same for the right neighbor, taking the max so both rules hold.
Worked example — ratings = [1, 3, 2, 2, 1]
start: 1 1 1 1 1 left->right: 1 2 1 1 1 (index 1 rated > index 0) right->left: 1 2 1 2 1 (index 3 > index 4; index 1 already 2 >= 2) total = 1 + 2 + 1 + 2 + 1 = 7
A left-to-right pass enforces "more than my left neighbor" but can't know about the right neighbor yet. You need a second pass in the opposite direction.
After the left pass, the right pass sets each child to max(current, rightNeighbor + 1) when its rating is higher on the right. The max keeps the left-side requirement intact while adding the right-side one.
No rule applies between equal neighbors, so a child no higher than either neighbor can stay at one — which is what keeps the total minimal.
| Relax until stable | Two passes | |
|---|---|---|
| Idea | Repeatedly bump any child violating a neighbor rule | Left-to-right then right-to-left, take the max |
| Time | O(n^2) | O(n) |
| Space | O(n) | O(n) |
The relaxation approach re-sweeps until nothing changes; the two directed passes reach the same assignment in linear time. Full code is in the Approaches selector below.
Key takeaway
Give everyone one candy, then do two passes: left-to-right so each child beats its left neighbor, and right-to-left taking the max so each also beats its right neighbor. Two O(n) passes give the minimum total that satisfies both sides.
candies = [1] * n for i in 1..n-1: if ratings[i] > ratings[i-1]: candies[i] = candies[i-1] + 1 for i in n-2..0: if ratings[i] > ratings[i+1]: candies[i] = max(candies[i], candies[i+1] + 1) return sum(candies)