1、两次遍历
class Solution {
public int candy(int[] ratings) {
int[] candies = new int[ratings.length];
int sum = 0;
candies[0] = 1;
for (int i = 1; i < ratings.length; i++) {
if (ratings[i] > ratings[i - 1])
candies[i] = candies[i - 1] + 1;
else
candies[i] = 1;
}
for (int i = ratings.length - 1; i >= 1; i--) {
if (ratings[i - 1] > ratings[i])
candies[i - 1] = Math.max(candies[i] + 1, candies[i - 1]);
sum += candies[i];
}
return sum + candies[0];
}
}
2、一次遍历
法一我们把每个小朋友的糖果数量保存到了数组里,最后求和,法二我们选择在遍历的过程中就直接求和,但是这次求和中 增加的糖果数量 并不一定就是这个小朋友应该分配的糖果数
为了理解这个算法,首先我们定义递增序列,递减序列,假设rating数组为123210,那么递增序列是什么,递减序列又是什么?中间这个3其实他的存在很暧昧,可以说他是递增序列的一部分,也可以说他是递减序列的一部分。但是我们定义,3只能属于一个序列。我们的算法是从前到后遍历rating数组,当遍历到rating=1以及之前时,3都属于增序列,当遍历到0时,就把3从增序列拿出来,让他属于减序列!那么理论说法就是:我们当前遍历到的减序列长度与和他相邻的增序列长度相等时(也就是dec = inc),就把暧昧数字从增序列取出来,然后让他属于减序列!
我们用pre储存递增序列中这一个小朋友应该分到的糖果数,同时也是目前为止递增序列的长度,inc也储存递增序列的长度(但是并不重复,具体看对于递减序列的操作) 可以看到,在递增序列中每次增加的糖果数就是 这一个小朋友应该分到的糖果数
我们用dec存储这次遍历中处于递减序列的第一个小朋友应该分得的糖果数(从左到右排序)。举个栗子,rating数组为123210。首先需要知道,我们是从第二个小朋友开始遍历的,对于我们第三次遍历,我们按顺序从前往后找到了第四个小朋友(rating = 2),此时他应该分得的糖果数为1,那么我们的dec正好是1。之后遍历到了第五个小朋友(rating=1),此时递减序列有了两个小朋友分别是(rating=2和rating=1),此时dec = 2,当我们遍历到第六个小朋友时,根据我们前面的定义,递减序列的第一个数字变成了3,此时递减序列为3210,那么减序列第一个小朋友需要分到的糖果数就是4,但是此时dec是3,所以我们还需要dec++
最后还需要解释一下这种遍历过程中求和算法的正确性,对于递增序列,其正确性不言而喻。因为此时pre存储的就是这个小朋友现在的糖果数,然后sum+=pre就可以正确计算递增序列小朋友的糖果数;对于递减序列,我们其实是倒着加的,为什么说是倒着呢,这里举一个栗子,还是rating数组为123210,对应的糖果数组candies为124321 ,我们规定从左加到右为正序,递增序列的计算是1+2+3,但是递减序列的计算为1+2+4。但是到这里可能会有疑问,递增序列明明是1,2 为什么算的是1+2+3。这是因为我们在计算过程中递增序列发生了变化!因为中间有一步,暧昧数字变成了递减序列的一部分,这时对于rating数组为123210的情况来说,在增序列中我们计算了1+2+3,减序列计算了1+2,因为此时遍历到了rating=0,也就是说,增序列多加了3,减序列少加了3+4,所以我们把rating=3放到减序列,相当于是在减序列加了3,因为这个加入者,减序列的长度也从上一次遍历的2变成了这一次遍历的4,所以dec还需要再次++!
不过为毛O(1)空间复杂度的解法内存消耗比O(n)空间复杂度的解法还要大
class Solution {
public int candy(int[] ratings) {
int[] candies = new int[ratings.length];
int sum = 1, dec = 0, inc = 1, pre = 1;
for (int i = 1; i < ratings.length; i++) {
//递增序列
if (ratings[i] >= ratings[i - 1]) {
dec = 0;
pre = ratings[i] == ratings[i - 1] ? 1 : pre + 1;
sum += pre;
inc = pre;
} else {
dec++;
if (dec == inc)
dec++;
sum += dec;
pre = 1;
}
}
return sum;
}
}