There are N children standing in a line. Each child is assigned a rating value.
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.
What is the minimum candies you must give?
Example 1:
Input: [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: [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.
题意:
给一堆小朋友分糖果,每个小孩都分配了一个数,分糖果的规则:
1.每个小朋友至少分到一颗糖
2.数字大的小朋友要比挨着他的数字小的小朋友分到更多的糖
请问至少需要多少糖果
解答:
首先我们需要考虑以下几种情形
1.数字连续下降的情况,那我们最少要分配(连续下降n小朋友)的方式为每次下降一个,n、n-1、n-2 .... 1,总和为 n*(n+1)/2,
在下面代码中,我们直接通过记录下降的次数来计算。
2.连续上升只需要不断将糖果数加一。
3.当前后相等时,糖果数直接降为一。
4.当持续下降超过范围后,我们需要将之前的部分垫高
例如 [1,4,3,2,0,1]按算法可以得到这样的图,一个方格代表一块糖

第二个小朋友和第三个小朋友的关系不对(原因是下降序列长度较大,导致起始过高,这时候我们需要将之前的增长序列的最后一个垫高)

基于以上思想,可以得到如下代码。
代码:
class Solution {
public int candy(int[] ratings) {
if (ratings == null || ratings.length == 0) return 0;
int total = 1, prev = 1, countDown = 0;
for (int i = 1; i < ratings.length; i++) {
if (ratings[i] >= ratings[i-1]) {
if (countDown > 0) {
total += countDown*(countDown+1)/2; // arithmetic progression
if (countDown >= prev) total += countDown - prev + 1; //need higher last stair of increase
countDown = 0;
prev = 1;
}
prev = ratings[i] == ratings[i-1] ? 1 : prev+1;
total += prev;
} else countDown++;
}
if (countDown > 0) { // if we were descending at the end
total += countDown*(countDown+1)/2;
if (countDown >= prev) total += countDown - prev + 1;
}
return total;
}
}
小朋友分糖果问题的算法解答
博客围绕给小朋友分糖果的问题展开。已知每个小朋友有一个数字,分糖规则是每人至少一颗,数字大的比相邻数字小的分得更多。解答时考虑数字连续下降、上升、相等及下降超范围等情形,最后给出了相应代码。
5万+

被折叠的 条评论
为什么被折叠?



