Problem Statement
Candy
There are n children standing in a line. Each child has a rating, given in the array ratings. You hand out candies with two rules: every child must get at least one candy, and any child with a higher rating than the kid right next to them must get more candies than that neighbor. The goal is to find the smallest total number of candies that follows both rules. The clever idea here is greedy. Greedy means we make the best local choice at each step (give each child the fewest candies that still satisfies the rules) and trust that these small best choices add up to the best total. We do this in two passes over the line: one going left to right, one going right to left.
Signals to notice
Brute force first
Iteratively adjust candies until all constraints are met — worst case. May require multiple passes. That instinct is useful because it follows the prompt literally, but it usually keeps revisiting work the problem is begging you to organize.
The key insight
Two passes: left-to-right ensures each child has more than their left neighbor if their rating is higher. Right-to-left ensures the same for right neighbors. Take the max at each position. Instead of recomputing the world every time, you preserve just enough context to let the next decision become obvious.
Trace it on ratings=[1,3,2,2,1]
init: candies=[1,1,1,1,1] left i=1: 3>1 -> candies[1]=2; i=2,3,4 not greater than left -> candies=[1,2,1,1,1] right i=3: 2>1 -> candies[3]=max(1,1+1)=2 -> candies=[1,2,1,2,1] right i=2: ratings 2==2, skip right i=1: 3>2 -> candies[1]=max(2,1+1)=2 (unchanged); i=0: 1<3 skip final candies=[1,2,1,2,1], sum=7 -> return 7
What must stay true
The left-to-right pass satisfies all left-neighbor constraints. The right-to-left pass satisfies all right-neighbor constraints. Taking the max of both ensures both are satisfied simultaneously. As long as that statement keeps holding, you can trust the steps built on top of it.
Shape of the loop
candies = [1]*n
for i in 1..n-1: # left-to-right
if ratings[i] > ratings[i-1]: candies[i] = candies[i-1] + 1
for i in n-2..0: # right-to-left
if ratings[i] > ratings[i+1]: candies[i] = max(candies[i], candies[i+1] + 1)
return sum(candies)Pseudocode only — the full worked solution lives in the Solution tab.
Easy way to go wrong
Doing only one pass — a single pass can't satisfy both directions simultaneously. The two-pass approach handles increasing and decreasing sequences independently. Most mistakes here are not about syntax; they come from losing track of what your state, pointer, or structure is supposed to mean.