Article Directory
One [topic category]
- Greedy Algorithm
Two [question difficulty]
- difficulty
Three [topic number]
- 135. Handing out candy
Four [title description]
- n children stand in a row. You are given an integer array ratings representing each child's rating.
- You need to distribute candy to these children according to the following requirements:
- Each child is assigned at least 1 candy.
- The child with the higher score of two adjacent children gets more candies.
- Please distribute candies to each child, calculate and return the minimum number of candies that need to be prepared.
Five [topic examples]
-
Example 1:
- Input: ratings = [1,0,2]
- Output: 5
- Explanation: You can distribute 2, 1, and 2 candies to the first, second, and third child, respectively.
-
Example 2:
- Input: ratings = [1,2,2]
- Output: 4
- Explanation: You can distribute 1, 2, and 1 candy to the first, second, and third children, respectively. The third child only gets 1 candy, which satisfies the two conditions in the title.
Six [problem-solving ideas]
- This question is difficult and not easy to think about. It mainly uses the greedy idea to traverse the array twice, from left to right and from right to left respectively, that is, to satisfy two rules:
- Left rule: traverse from left to right, because the title requires each person to have at least one candy, so the first person defaults to one candy, and then traverse from the second person, if the iiThe score of the i person is greater than the i − 1 i-1i−1 person's score, according to the topic requirements, sectioniiThe number of candies of person i is greater than that of i − 1 i-1i−1 person has one more candy; if theiiThe score of the i person is less than or equal to thei − 1 i-1i−1 person's rating, theni − 1 i-1i−The number of candies for 1 person is the default one candy. Of course, you need to use an array to store the number of candies for each person
- Right rule: traverse from right to left, because the title requires each person to have at least one candy, so the last person defaults to a candy, and then traverse from the penultimate person, if the iiThe score of the i person is greater than thei + 1 i+1i+1 person's score, according to the topic requirements, sectioniiThe number of candies of the i person is greater than that of the i + 1 i+1i+1 person has one more candy; if theiiThe score of the i person is less than or equal to thei + 1 i+1i+1 person's rating, theni − 1 i-1i−The number of candies for 1 person is the default one candy. At this point, another array needs to be used to store the number of candies for each person
- Finally, calculate the total number of candies, and traverse the array obtained above, for the iiPerson i must satisfy both the left rule and the right rule, so take the maximum value of the two
- Finally return the result
Seven [title prompt]
- n = = r a t i n g s . l e n g t h n == ratings.length n==ratings.length
- 1 < = n < = 2 ∗ 1 0 4 1 <= n <= 2 * 10^4 1<=n<=2∗104
- 0 < = r a t i n g s [ i ] < = 2 ∗ 1 0 4 0 <= ratings[i] <= 2 * 10^4 0<=ratings[i]<=2∗104
Eight 【Time Frequency】
- Time complexity: O ( n ) O(n)O ( n ) , wherennn is the length of the incoming array
- Space Complexity: O ( n ) O(n)O ( n ) , wherennn is the length of the incoming array
Nine [code implementation]
- Java language version
class Solution {
public int candy(int[] ratings) {
int len = ratings.length;
int[] left = new int[len];
int[] right = new int[len];
left[0] = 1;
for(int i = 1;i < len;i++){
left[i] = ratings[i] > ratings[i - 1] ? left[i - 1] + 1 : 1;
}
right[len - 1] = 1;
for(int i = len - 2;i>=0;i--){
right[i] = ratings[i] > ratings[i + 1] ? right[i + 1] + 1 : 1;
}
int res = 0;
for(int i = 0;i<len;i++){
res += Math.max(left[i],right[i]);
}
return res;
}
}
- C language version
int candy(int* ratings, int ratingsSize)
{
int* left = (int*)malloc(sizeof(int) * ratingsSize);
int* right = (int*)malloc(sizeof(int) * ratingsSize);
left[0] = 1;
for(int i = 1;i<ratingsSize;i++)
{
left[i] = ratings[i] > ratings[i - 1] ? left[i - 1] + 1 : 1;
}
right[ratingsSize - 1] = 1;
for(int i = ratingsSize - 2;i>=0;i--)
{
right[i] = ratings[i] > ratings[i + 1] ? right[i + 1] + 1 : 1;
}
int res = 0;
for(int i = 0;i<ratingsSize;i++)
{
res += fmax(left[i],right[i]);
}
return res;
}
- Python version
class Solution:
def candy(self, ratings: List[int]) -> int:
N = len(ratings)
left = [0] * N
right = [0] * N
left[0] = 1
for i in range(1,N):
left[i] = left[i - 1] + 1 if ratings[i] > ratings[i - 1] else 1
right[N - 1] = 1
for i in range(N - 2,-1,-1):
right[i] = right[i + 1] + 1 if ratings[i] > ratings[i + 1] else 1
res = 0
for i in range(0,N):
res += max(left[i],right[i])
return res
Ten【Submission results】
-
Java language version
-
C language version
-
Python language version