Distribute candies among children

Last Updated : 6 Sep, 2025

Given an array arr[] where each element represents the rating of a child, find the minimum number of candies required to distribute among all children under the following conditions:

  • Every child must receive at least one candy.
  • A child with a higher rating than their immediate neighbor(s) must receive more candies than that neighbor.

Examples:

Input: arr[] = [1, 2, 3, 4, 5]
Output: 15
Explanation: According to the rule, if a child’s rating is greater than the neighbor, he must get more candy than the neighbor.
Child 0 → rating 1 → gets 1 candy
Child 1 → rating 2 → greater than 1 → gets 2 candies
Child 2 → rating 3 → greater than 2 → gets 3 candies
Child 3 → rating 4 → greater than 3 → gets 4 candies
Child 4 → rating 5 → greater than 4 → gets 5 candies
Total candies are 1 + 2 + 3 + 4 + 5 = 15.

Input: arr[] = [9, 9, 9, 9]
Output: 4
Explanation: No child has a strictly greater rating than the neighbor. So, each child only needs the minimum 1 candy.

Try It Yourself
redirect icon

[Approach 1] Greedy Approach with Dual Traversal - O(n) Time and O(n) Space

We need to ensure each student has more candies than both of their neighbors if their score is higher.

To handle the left neighbor, we traverse left → right: if a student’s score is higher than the one on the left, give them more candies.

To handle the right neighbor, we traverse right → left: if a student’s score is higher than the one on the right, give them more candies.

Finally, for each student we take the sum of maximum from both passes.

Why does taking the maximum work?

Every student must satisfy both neighbors:

  • The left-to-right pass ensures fairness with the left neighbor (if a student has a higher score, they get more candies).
  • The right-to-left pass ensures fairness with the right neighbor.

But a student might need more candies to satisfy one side than the other. To keep the rule valid in both directions at once, we give them the maximum of the two counts. This way, no student violates the rule with either neighbor, while still keeping the distribution minimal.

C++
#include <iostream>
#include <vector>

using namespace std;

int minCandy(vector<int> &arr) {
    int n = arr.size();

    vector<int> leftcandy(n, 1);
    vector<int> rightcandy(n, 1);

    // left pass
    for (int i = 1; i < n; i++) {
        if (arr[i] > arr[i - 1])
            leftcandy[i] = leftcandy[i - 1] + 1;
    }

    // right pass
    for (int i = n - 2; i >= 0; i--){
        if (arr[i] > arr[i + 1])
            rightcandy[i] = rightcandy[i + 1] + 1;
    }

    // Calculate final answer
    int ans = 0;
    for (int i = 0; i < n; i++) {
        
        // Take max at each position
        ans += max(leftcandy[i], rightcandy[i]); 
    }

    return ans;
}

int main() {
    vector<int> arr = {1,2,3,4,5};

    cout << minCandy(arr);
}
Java
import java.util.Arrays;

public class GfG {
    public static int minCandy(int[] arr) {
        int n = arr.length;

        int[] leftCandy = new int[n];
        int[] rightCandy = new int[n];
        Arrays.fill(leftCandy, 1);
        Arrays.fill(rightCandy, 1);

        // Left pass
        for (int i = 1; i < n; i++) {
            if (arr[i] > arr[i - 1])
                leftCandy[i] = leftCandy[i - 1] + 1;
        }

        // Right pass
        for (int i = n - 2; i >= 0; i--) {
            if (arr[i] > arr[i + 1])
                rightCandy[i] = rightCandy[i + 1] + 1;
        }

        // Calculate final answer
        int ans = 0;
        for (int i = 0; i < n; i++) {
            
            // Take max at each position
            ans += Math.max(leftCandy[i], rightCandy[i]);
        }

        return ans;
    }

    public static void main(String[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5 };

        System.out.println(minCandy(arr));
    }
}
Python
import array

def minCandy(arr):
    n = len(arr)

    leftcandy = array.array('i', [1] * n)
    rightcandy = array.array('i', [1] * n)

    # left pass
    for i in range(1, n):
        if arr[i] > arr[i - 1]:
            leftcandy[i] = leftcandy[i - 1] + 1

    # right pass
    for i in range(n - 2, -1, -1):
        if arr[i] > arr[i + 1]:
            rightcandy[i] = rightcandy[i + 1] + 1

    # calculate final answer
    return sum(max(leftcandy[i], rightcandy[i]) for i in range(n))

if __name__ == "__main__":
    arr = array.array('i', [1, 2, 3, 4, 5 ])
    print(minCandy(arr))
C#
using System;

class GfG {
    static int minCandy(int[] arr) {
        int n = arr.Length;

        int[] leftCandy = new int[n];
        int[] rightCandy = new int[n];

        Array.Fill(leftCandy, 1);
        Array.Fill(rightCandy, 1);

        // Left pass
        for (int i = 1; i < n; i++) {
            if (arr[i] > arr[i - 1])
                leftCandy[i] = leftCandy[i - 1] + 1;
        }

        // Right pass
        for (int i = n - 2; i >= 0; i--) {
            if (arr[i] > arr[i + 1])
                rightCandy[i] = rightCandy[i + 1] + 1;
        }

        // Calculate final answer
        int ans = 0;
        for (int i = 0; i < n; i++) {
            ans += Math.Max(leftCandy[i], rightCandy[i]);
        }

        return ans;
    }

    static void Main() {
        int[] arr = {1, 2, 3, 4, 5 };
        Console.WriteLine(minCandy(arr));
    }
}
JavaScript
function minCandy(arr) {
    let n = arr.length;

    let leftCandy = new Array(n).fill(1);
    let rightCandy = new Array(n).fill(1);

    // Left pass
    for (let i = 1; i < n; i++) {
        if (arr[i] > arr[i - 1]) {
            leftCandy[i] = leftCandy[i - 1] + 1;
        }
    }

    // Right pass
    for (let i = n - 2; i >= 0; i--) {
        if (arr[i] > arr[i + 1]) {
            rightCandy[i] = rightCandy[i + 1] + 1;
        }
    }

    // Calculate final answer
    let ans = 0;
    for (let i = 0; i < n; i++) {
        ans += Math.max(leftCandy[i], rightCandy[i]);
    }

    return ans;
}

// Driver code
let arr = [1, 2, 3, 4, 5 ];
console.log(minCandy(arr));

Output
15

[Approach 2] Greedy Approach Using Rising and Falling Slopes - O(n) Time and O(1) Space

The key idea is that every valid candy distribution forms slopes of increasing and decreasing ratings.

On an increasing slope, each child must get 1 more candy than the previous one. This ensures all local rising conditions are satisfied.

On a decreasing slope, the same logic applies in reverse, so each child gets 1 more than the next.

At a peak, both conditions apply. By subtracting the smaller overlap, we avoid double-counting but still guarantee the peak has more candies than both neighbors.


Steps to solve the problem:

  • Start by giving each child 1 candy (hence total = n).
  • Move from left to right, comparing the current rating with the previous one.
  • If two adjacent children have the same rating, just move forward (no extra candy is needed).
  • While the current rating is higher than the previous one, keep increasing candies for each child (peak++) and add to total.(Increasing sequence).
  • While the current rating is lower than the previous one, keep decreasing (valley++) and add to total (decreasing sequence).
  • The peak child is counted in both increasing and decreasing sequences, so subtract min(peak, valley) to remove the extra candy.
  • Repeat the process until all children are covered.
C++
#include <iostream>
#include <vector>
using namespace std;

int minCandy(vector<int> &arr) {
    int n = arr.size();

    // create variable to store count
    // of candies, initlize it with n
    int total = n;
    int i = 1;

    // Traverse from left to right
    while (i < n) {

        // if rating of ith children is
        // equal to the previous children
        if (arr[i] == arr[i - 1]) {
            i++;
            continue;
        }

        // to find the increasing sequence
        int peak = 0;
        while (i < n && arr[i] > arr[i - 1]) {
            peak++;
            total += peak;
            i++;
        }

        if (i == n) {
            return total;
        }

        // to find the decreasing sequence
        int valley = 0;
        while (i < n && arr[i] < arr[i - 1]) {
            valley++;
            total += valley;
            i++;
        }

        // remove the extra candy added twice
        total -= min(peak, valley);
    }

    return total;
}

int main() {
    vector<int> arr = {1, 2, 3, 4, 5 };
    cout << minCandy(arr);
    return 0;
}
Java
class GfG {
    
    static int minCandy(int[] arr) {
        int n = arr.length;

        // create variable to store count
        // of candies, initialize it with n
        int total = n;
        int i = 1;

        // Traverse from left to right
        while (i < n) {

            // if rating of ith children is
            // equal to the previous children
            if (arr[i] == arr[i - 1]) {
                i++;
                continue;
            }

            // to find the increasing sequence
            int peak = 0;
            while (i < n && arr[i] > arr[i - 1]) {
                peak++;
                total += peak;
                i++;
            }

            if (i == n) {
                return total;
            }

            // to find the decreasing sequence
            int valley = 0;
            while (i < n && arr[i] < arr[i - 1]) {
                valley++;
                total += valley;
                i++;
            }

            // remove the extra candy added twice
            total -= Math.min(peak, valley);
        }

        return total;
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5 };
        System.out.println(minCandy(arr));
    }
}
Python
def minCandy(arr):
    n = len(arr)

    # create variable to store count
    # of candies, initialize it with n
    total = n
    i = 1

    # Traverse from left to right
    while i < n:

        # if rating of ith children is
        # equal to the previous children
        if arr[i] == arr[i - 1]:
            i += 1
            continue

        # to find the increasing sequence
        peak = 0
        while i < n and arr[i] > arr[i - 1]:
            peak += 1
            total += peak
            i += 1

        if i == n:
            return total

        # to find the decreasing sequence
        valley = 0
        while i < n and arr[i] < arr[i - 1]:
            valley += 1
            total += valley
            i += 1

        # remove the extra candy added twice
        total -= min(peak, valley)

    return total


if __name__ == "__main__":
    arr = [1, 2, 3, 4, 5 ]
    print(minCandy(arr))
C#
using System;

class GfG {
    
    static int minCandy(int[] arr) {
        int n = arr.Length;

        // create variable to store count
        // of candies, initialize it with n
        int total = n;
        int i = 1;

        // Traverse from left to right
        while (i < n) {

            // if rating of ith children is
            // equal to the previous children
            if (arr[i] == arr[i - 1]) {
                i++;
                continue;
            }

            // to find the increasing sequence
            int peak = 0;
            while (i < n && arr[i] > arr[i - 1]) {
                peak++;
                total += peak;
                i++;
            }

            if (i == n) {
                return total;
            }

            // to find the decreasing sequence
            int valley = 0;
            while (i < n && arr[i] < arr[i - 1]) {
                valley++;
                total += valley;
                i++;
            }

            // remove the extra candy added twice
            total -= Math.Min(peak, valley);
        }

        return total;
    }

    public static void Main() {
        int[] arr = {1, 2, 3, 4, 5 };
        Console.WriteLine(minCandy(arr));
    }
}
JavaScript
function minCandy(arr) {
    const n = arr.length;

    // create variable to store count
    // of candies, initialize it with n
    let total = n;
    let i = 1;

    // Traverse from left to right
    while (i < n) {

        // if rating of ith children is
        // equal to the previous children
        if (arr[i] === arr[i - 1]) {
            i++;
            continue;
        }

        // to find the increasing sequence
        let peak = 0;
        while (i < n && arr[i] > arr[i - 1]) {
            peak++;
            total += peak;
            i++;
        }

        if (i === n) {
            return total;
        }

        // to find the decreasing sequence
        let valley = 0;
        while (i < n && arr[i] < arr[i - 1]) {
            valley++;
            total += valley;
            i++;
        }

        // remove the extra candy added twice
        total -= Math.min(peak, valley);
    }

    return total;
}

// Driver Code

const arr = [1, 2, 3, 4, 5 ];
console.log(minCandy(arr));

Output
15
Comment