AlgoMaster Logo

Candy

hardFrequency7 min readUpdated June 23, 2026

Understanding the Problem

We have a line of children, each with a rating. We need to hand out candies so that every child gets at least one, and any child whose rating is strictly higher than an immediate neighbor gets more candies than that neighbor. The goal is to minimize the total number of candies.

Each child except the two at the ends has two neighbors, so the constraint must hold in both directions at once. If child 3 has a higher rating than both child 2 and child 4, then child 3's candy count must exceed both of those neighbors.

The rule "higher rating means more candies" applies only to strict inequality. If two adjacent children have the same rating, neither is required to get more than the other, so both can receive a single candy.

Key Constraints:

  • 1 <= n <= 2 * 10^4 → An O(n^2) solution is around 4 10^8 operations in the worst case, which risks a time limit. The target is O(n). The largest possible total (a strictly increasing line of 20,000 children) is 1 + 2 + ... + 20,000, about 2 10^8, so the answer fits in a 32-bit integer.
  • 0 <= ratings[i] <= 2 * 10^4 → Ratings are non-negative integers, and two children can share a rating. Equal neighbors impose no ordering on candy counts.

Approach 1: Brute Force (Iterative Correction)

Intuition

Give every child 1 candy, then repeatedly scan the array and fix violations until none remain. A violation is a position where a child has a higher rating than a neighbor but does not have more candies. The fix raises that child's count to the neighbor's count plus one.

Each correction can create a new violation against the corrected child's other neighbor, so several passes may be needed before the array stabilizes.

Algorithm

  1. Initialize a candies array of size n, with every element set to 1.
  2. Set a flag changed = true.
  3. While changed is true:
    • Set changed = false.
    • For each child i from 0 to n-1:
      • If ratings[i] > ratings[i-1] and candies[i] <= candies[i-1], set candies[i] = candies[i-1] + 1 and mark changed = true.
      • If ratings[i] > ratings[i+1] and candies[i] <= candies[i+1], set candies[i] = candies[i+1] + 1 and mark changed = true.
  4. Return the sum of the candies array.

Example Walkthrough

Input:

0
1
1
0
2
2
ratings

Pass 1: Check each child. Child 0 has rating 1 > child 1's rating 0 and candies[0]=1 <= candies[1]=1, so raise candies[0] to 2. Child 2 has rating 2 > child 1's rating 0 and candies[2]=1 <= candies[1]=1, so raise candies[2] to 2. Result:

0
2
1
1
2
2
candies

Pass 2: No violations found. Done. Total = 2 + 1 + 2 = 5.

Code

The repeated passes redo work that two directed passes can settle once: one forward pass for the left-neighbor constraint, one backward pass for the right-neighbor constraint.

Approach 2: Two-Pass Greedy

Intuition

The candy requirement combines two independent constraints. The left constraint says: if ratings[i] > ratings[i-1], then candies[i] > candies[i-1]. The right constraint says: if ratings[i] > ratings[i+1], then candies[i] > candies[i+1].

A left-to-right pass can enforce the left constraint perfectly, because by the time we reach position i, we've already finalized position i-1. Similarly, a right-to-left pass can enforce the right constraint. At each position, the answer is the maximum of what the two passes require, because we need to satisfy both constraints simultaneously.

Algorithm

  1. Create a candies array of size n, initialized to all 1s.
  2. Left-to-right pass: For i from 1 to n-1, if ratings[i] > ratings[i-1], set candies[i] = candies[i-1] + 1.
  3. Right-to-left pass: For i from n-2 down to 0, if ratings[i] > ratings[i+1], set candies[i] = max(candies[i], candies[i+1] + 1).
  4. Return the sum of the candies array.

Example Walkthrough

1Input ratings array
0
1
1
3
2
5
3
3
4
2
5
1
1/8
1Initialize all candies to 1
0
1
1
1
2
1
3
1
4
1
5
1
1/8

Code

The two-pass approach is O(n) time, which is optimal, but it stores a full candies array. The final approach computes the total in a single pass with O(1) extra space.

Approach 3: Single-Pass with Slope Counting (O(1) Space)

Intuition

Read left to right, the ratings form a sequence of uphills and downhills. On an uphill (ratings increasing), the minimum candy counts are 1, 2, 3, ... On a downhill (ratings decreasing), they count back down to 1. The two slopes interact only at the peak between them, which must clear both sides: it needs max(up, down) + 1 candies, where up and down are the lengths of the slopes on either side.

This structure lets us compute the total without storing per-child counts. We track three values: up (current ascending run length), down (current descending run length), and peak (the ascending run length at the most recent peak). Going up, the new child gets up + 1 candies. Going down, the new child gets 1 candy and every child already on the downhill needs one more candy than before, which comes to down candies in total, so adding down at each step applies the retroactive increases without revisiting the array. Once down exceeds peak, each further step also forces one more candy onto the peak itself, so we add 1 extra. Equal adjacent ratings break the slope: the new child gets 1 candy and all three counters reset.

Algorithm

  1. Initialize total = 1, up = 0, down = 0, peak = 0.
  2. For each position i from 1 to n-1:
    • If ratings[i] > ratings[i-1] (going up): increment up, reset down = 0, set peak = up, add up + 1 to total.
    • If ratings[i] < ratings[i-1] (going down): increment down, reset up = 0, add down to total. If down > peak, add 1 more.
    • If ratings[i] == ratings[i-1] (flat): reset up, down, peak to 0, add 1 to total.
  3. Return total.

Example Walkthrough

1Start: total=1 (child 0 gets 1), up=0, down=0, peak=0
0
1
start
1
3
2
5
3
3
4
2
5
1
1/7

Code