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.length
1 <= n <= 2 * 104
0 <= 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;}
}
总结 :
该题需要两个维度进行考虑,先考虑一边,再去考虑另外一边,不能同时考虑,要不都顾不过来.
出现两种维度的情况下,需要先确定好一个维度,在确定另外一个维度