135. 分发糖果
难度困难1086
n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。
你需要按照以下要求,给这些孩子分发糖果:
- 每个孩子至少分配到 
1个糖果。 - 相邻两个孩子评分更高的孩子会获得更多的糖果。
 
请你给每个孩子分发糖果,计算并返回需要准备的 最少糖果数目 。
示例 1:
输入:ratings = [1,0,2] 输出:5 解释:你可以分别给第一个、第二个、第三个孩子分发 2、1、2 颗糖果。
示例 2:
输入:ratings = [1,2,2]
输出:4
解释:你可以分别给第一个、第二个、第三个孩子分发 1、2、1 颗糖果。
     第三个孩子只得到 1 颗糖果,这满足题面中的两个条件。 
 
提示:
n == ratings.length1 <= n <= 2 * 1040 <= ratings[i] <= 2 * 104
思路
先理解一下题意,他说是要根据孩子评分给每一个孩子分糖果.每一个孩子至少分配一个糖果,还有一重要的点是,相邻两个孩子评分更高的孩子会获得更多的糖果
意思就是对于一个孩子来说,除了两边,既与左面孩子相邻,也与右边孩子相邻.
所以我们就要一边一边进行考虑
- 右孩子大于左孩子的情况(需要从前往后遍历)
 - 左孩子大于右孩子的情况(需要从后往前遍历)
 
但要保证对于每一个孩子来说,他既要比左面糖果多也要比右面糖果多,所以要取最大值.


思路总结
- 从前往后遍历一遍数组,如果该孩子比它左边孩子评分高,就比左边孩子多一个糖果ratings[i]>ratings[i-1] ==> res[i] = res[i-1] +1; 右边孩子比左边孩子糖果多,达到局部最优,最终给所有孩子分完,全局最优
 - 从后往前遍历一边数组,如果该孩子比它右边孩子评分高,就比右边孩子多一个糖果ratings[i]>ratings[i+1] ==> res[i] = res[i+1] +1;左边孩子比右边孩子糖果多,达到局部最优,最终给所有孩子分完,全局最优
 - 对于一个孩子,既要比左面孩子评分高,也比右边孩子评分高,所以要取最大
 - 最后将结果数组res累加即可
 
第二步和第三步在代码层次可以合起来,因为只有一个孩子,既要比左面孩子评分高,也比右边孩子评分高,才会既要比左边孩子分的糖果多也要比右边孩子分的糖果多,==>res[i] = Math.max(res[i],res[i+1]+1) ; res[i]为已经计算好的了,一个孩子比它左面分高 res[i+1]+1,一个孩子比它右面孩子分高,取最大即可.
class Solution {
    public int candy(int[] ratings) {
        int[] res = new int[ratings.length];
        Arrays.fill(res,1);//每个孩子至少分配到 1 个糖果。
        for(int i =1;i<ratings.length;++i) {
            if(ratings[i]>ratings[i-1]) {//一个孩子比它左面孩子评分高,就多分一个糖果
                res[i] = res[i-1] + 1;
            }
        }
        int sum = 0;
        for(int i =ratings.length-2;i>=0;--i) {
            if(ratings[i]>ratings[i+1]) {//一个孩子比它右面孩子评分高,就多分一个糖果
                //对于一个孩子既要比左边孩子评分高也比右边孩子评分高,所以糖果要比两个都多,所以要取最大==>糖果既要比左面多也比右边多
                res[i] = Math.max(res[i],res[i+1]+1);
            }
        }
        int ans = 0;
        for(int i=0;i<ratings.length;++i) ans += res[i];
        return ans;
    }
} 
总结 :
该题需要两个维度进行考虑,先考虑一边,再去考虑另外一边,不能同时考虑,要不都顾不过来.
出现两种维度的情况下,需要先确定好一个维度,在确定另外一个维度













![Java高效率复习-坦克大战[Java基础合集]](https://img-blog.csdnimg.cn/9661c9efddb244e897153b3bc7ce7501.png)




