HomeLeetcode135. Candy - Leetcode Solutions

135. Candy – Leetcode Solutions

Description

There are n children standing in a line. Each child is assigned a rating value given in the integer array ratings.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

Return the minimum number of candies you need to have to distribute the candies to the children.

Examples:

Example 1:

Input: ratings = [1,0,2]
Output: 5
Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively.

Example 2:

Input: ratings = [1,2,2]
Output: 4
Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively.
The third child gets 1 candy because it satisfies the above two conditions.

Solution in Python

To solve the problem of distributing candies based on the ratings, we can use a two-pass greedy algorithm. The idea is to ensure that each child gets more candies than their neighbors if they have a higher rating, while also ensuring that each child gets at least one candy.

Approach:

  1. Initialize Candies Array: Create an array candies of the same length as ratings, initialized with 1 candy for each child because each child must have at least one candy.
  2. Left-to-Right Pass: Traverse the ratings array from left to right. For each child, if the current child’s rating is higher than the previous child’s rating, increment the current child’s candy count to be one more than the previous child’s candy count.
  3. Right-to-Left Pass: Traverse the ratings array from right to left. For each child, if the current child’s rating is higher than the next child’s rating, update the current child’s candy count to be the maximum of the current candy count and one more than the next child’s candy count.
  4. Sum Up Candies: Sum all the values in the candies array to get the minimum number of candies required.
Python
from typing import List

class Solution:
    def candy(self, ratings: List[int]) -> int:
        n = len(ratings)
        if n == 0:
            return 0
        
        # Step 1: Initialize candies array with 1 candy for each child
        candies = [1] * n
        
        # Step 2: Left-to-right pass
        for i in range(1, n):
            if ratings[i] > ratings[i - 1]:
                candies[i] = candies[i - 1] + 1
        
        # Step 3: Right-to-left pass
        for i in range(n - 2, -1, -1):
            if ratings[i] > ratings[i + 1]:
                candies[i] = max(candies[i], candies[i + 1] + 1)
        
        # Step 4: Sum up the candies
        return sum(candies)

Explanation:

  1. Initialization: We start by initializing the candies array with all elements set to 1, as every child must have at least one candy.
  2. Left-to-Right Pass:
    • For each child from the second to the last, we check if their rating is greater than the previous child’s rating.
    • If so, we give the current child one more candy than the previous child.
  3. Right-to-Left Pass:
    • For each child from the second to the last (moving backwards), we check if their rating is greater than the next child’s rating.
    • If so, we update the current child’s candy count to be the maximum of its current candy count or one more than the next child’s candy count. This ensures that we maintain the property from both directions.
  4. Sum Up Candies: Finally, we sum up all the values in the candies array to get the total number of candies required.

This algorithm ensures that both constraints are met efficiently, with a time complexity of O(n) and a space complexity of O(n).

Solution in Javascript

JavaScript
/**
 * @param {number[]} ratings
 * @return {number}
 */
var candy = function(ratings) {
    const n = ratings.length;
    if (n === 0) return 0;
    
    // Step 1: Initialize candies array with 1 candy for each child
    const candies = new Array(n).fill(1);
    
    // Step 2: Left-to-right pass
    for (let i = 1; i < n; i++) {
        if (ratings[i] > ratings[i - 1]) {
            candies[i] = candies[i - 1] + 1;
        }
    }
    
    // Step 3: Right-to-left pass
    for (let i = n - 2; i >= 0; i--) {
        if (ratings[i] > ratings[i + 1]) {
            candies[i] = Math.max(candies[i], candies[i + 1] + 1);
        }
    }
    
    // Step 4: Sum up the candies
    return candies.reduce((a, b) => a + b, 0);
};

Solution in Java

Java
class Solution {
    public int candy(int[] ratings) {
        int n = ratings.length;
        if (n == 0) return 0;
        
        // Step 1: Initialize candies array with 1 candy for each child
        int[] candies = new int[n];
        for (int i = 0; i < n; i++) {
            candies[i] = 1;
        }
        
        // Step 2: Left-to-right pass
        for (int i = 1; i < n; i++) {
            if (ratings[i] > ratings[i - 1]) {
                candies[i] = candies[i - 1] + 1;
            }
        }
        
        // Step 3: Right-to-left pass
        for (int i = n - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1]) {
                candies[i] = Math.max(candies[i], candies[i + 1] + 1);
            }
        }
        
        // Step 4: Sum up the candies
        int totalCandies = 0;
        for (int candy : candies) {
            totalCandies += candy;
        }
        
        return totalCandies;
    }
}

Solution in C#

C#
public class Solution {
    public int Candy(int[] ratings) {
        int n = ratings.Length;
        if (n == 0) return 0;

        // Step 1: Initialize candies array with 1 candy for each child
        int[] candies = new int[n];
        for (int i = 0; i < n; i++) {
            candies[i] = 1;
        }

        // Step 2: Left-to-right pass
        for (int i = 1; i < n; i++) {
            if (ratings[i] > ratings[i - 1]) {
                candies[i] = candies[i - 1] + 1;
            }
        }

        // Step 3: Right-to-left pass
        for (int i = n - 2; i >= 0; i--) {
            if (ratings[i] > ratings[i + 1]) {
                candies[i] = Math.Max(candies[i], candies[i + 1] + 1);
            }
        }

        // Step 4: Sum up the candies
        int totalCandies = 0;
        for (int i = 0; i < n; i++) {
            totalCandies += candies[i];
        }

        return totalCandies;
    }
}

Subscribe
Notify of

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Popular