leetcode记录-135-分发糖果-贪心

135 Candy

题目

在这里插入图片描述

思路

  1. 前两个先给,大的1个小的两个,从第三个开始,每个与前面的比较,如果比前面的大,其值为前面的+1,如果比前面的小,给这个赋值为1,然后看前面的是否为1,如果为1,判断前两个差几,如果差1,给前面的都+1,如果差的>1,给前面一个+1 —— 得不到最小
  2. 前两个先给,大的1个小的两个,从第三个开始,每个与前面的比较,如果比前面的大,其值为前面的+1,如果比前面的小,赋值为前面的-1,如果不够减,给前面的都+1。——直接前面的-1会存在分配的还是太大问题,从赋值为1转化为这个是因为觉得直接赋值为1,如果后面的更小,前面需要再加,考虑的太多,忽视了其实考虑当前递减序列即可——用一个值记录当前递减序列最大值,如果后面的比前面的小,就给除第一个外所有的+1,保证递增序列的第一个一定为1。
  3. 因为要满足邻居评分高的获得的糖果多,存在左邻居和右邻居两种情况,可以分为两个局部最优,然后得到全局最优,至于全局最优为什么取两个局部最优的最大值。—— 因为从右往左满足左边比右边大时一定比右边多的情况,为所有递减子列,对于递减子列,从左到右的情况,除第一个外都为1,所以取最大值既能满足左规则,也能满足右规则。(只可意会说出来好绕)
    思考样例:3 2 1;4 3 2 3;4 3 4 3

代码

class Solution {
    public int candy(int[] ratings) {
       int[] per_num = new int[ratings.length];
        Arrays.fill(per_num,1);
        int[] per_num_right = new int[ratings.length];
        Arrays.fill(per_num_right,1);
        for (int i = 1; i < ratings.length; i++) {
            if (ratings[i]>ratings[i-1])
                per_num[i] = per_num[i-1]+1;
        }
        int num = per_num[ratings.length-1];
//        注意,从右往左的时候,右边第一个不能从1开始
        for (int i = ratings.length-1; i >0; i--) {
            if (ratings[i-1]>ratings[i])
                per_num_right[i-1] = per_num_right[i]+1;
            num+=Math.max(per_num_right[i-1],per_num[i-1]);
        }
        return num;
    }
}

技巧

  1. 数组整体赋值:Arrays.fill(result, 1);
  2. 数组每个元素操作,可以用
    for (int num : result) {
    sum += num;
    }
  3. 比大小:Math.max(left[i], right);
  4. 数列由一系列的递增子列和递减子列组成,当有与数列相关的大小问题时,考虑此题思路。

好的题解

  1. 左规则右规则分别遍历,取每个元素最大值。
  2. 每个元素的值为从其出发向左的递减序列长度和向右的递减序列长度的最大值。(同时满足两种情况,长的一边的最边的元素取值一定为1)
  3. 总之思路都是围绕一个个局部最高点的操作展开
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值