贪心 135. 分发糖果

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;
    }
}

总结 :

该题需要两个维度进行考虑,先考虑一边,再去考虑另外一边,不能同时考虑,要不都顾不过来.

出现两种维度的情况下,需要先确定好一个维度,在确定另外一个维度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值