思路:看到本题最初的大的想法就是,在遍历中确定每一个孩子应该分到的糖果,然后用一个累加器记录,实际上是不太可行的,在遍历中,每个孩子分到的糖果同时受到左右两边相邻孩子的影响,在遍历中需要保存之前的结果用于之后的分配,在单次的遍历中很难完成,所以我们需要使用两次遍历,分别考虑左右两边相邻节点的大小问题,同时用一个糖果数组来记录保存每个孩子分的糖果,遍历的时候直接在这个数组的基础上进行更新即可
所以我们先要创建糖果数组并进行初始化赋值,之后的遍历都在这个基础上进行更新,由于每个孩子至少要1个糖果所以所有的位置都先初始化为1
int[] candyNums = new int[ratings.length];
// 初始化为1
for (int i = 0; i < candyNums.length; i++) {
candyNums[i] = 1;
}
之后我们先进行从前到后的遍历 考虑右边大于左边的情况,如果符合条件在左边的基础上加一即可
// 如果右边的比左边的大 就加一
for (int i = 1; i < ratings.length ; i++) {
if (ratings[i] > ratings[i-1]){
candyNums[i] = candyNums[i-1] +1;
}
}
最后进行后到前的遍历 考虑的是左边大于右边的情况,这里有一个易错的点,在符合条件的时候,不仅仅是在右边的基础上加一,而是需要同时考虑其第一次遍历之后的糖果数量,因为对于一个位置来说需要同时满足左右两边相邻孩子的大小的情况,第一次遍历之后的结果是符合右边大于左边的情况,第二层遍历之后的结果符合左边大于右边的情况,同时满足两种情况则需要取两种情况中糖果数量最大的一种
for (int i = ratings.length - 2; i >=0 ; i--) {
if (ratings[i] > ratings[i+1] ){
// 这里有两种情况 一种是第一次遍历中得到的 第二个是这次遍历中由右边加1得到的
// 取二者最大的 因为最大的才能同时满足要求
candyNums[i] = Math.max(candyNums[i + 1] +1,candyNums[i]);
}
}
整体如下
class Solution {
public int candy(int[] ratings) {
int[] candyNums = new int[ratings.length];
// 初始化为1
for (int i = 0; i < candyNums.length; i++) {
candyNums[i] = 1;
}
// 如果右边的比左边的大 就加一
for (int i = 1; i < ratings.length ; i++) {
if (ratings[i] > ratings[i-1]){
candyNums[i] = candyNums[i-1] +1;
}
}
for (int i = ratings.length - 2; i >=0 ; i--) {
if (ratings[i] > ratings[i+1] ){
// 这里有两种情况 一种是第一次遍历中得到的 第二个是这次遍历中由右边加1得到的
// 取二者最大的 因为最大的才能同时满足要求
candyNums[i] = Math.max(candyNums[i + 1] +1,candyNums[i]);
}
}
return Arrays.stream(candyNums).sum();
}
}