代码随想录刷LeetCode | 贪心刷题回顾01

 前沿:撰写博客的目的是为了再刷时回顾进一步完善,其次才是以教为学,所以如果有些博客写的较简陋,是为了保持进度不得已而为之,还请大家多多见谅。

预:看到题目后的思路和实现的代码。

见:参考答案展示。

感思:对比答案后的思考,与之前做过的题目是否有关联。

行:

(1)对于没做出来的题目,阅读答案后重新做一遍;

(2)下次做题可以尝试改善的方向;

(3)有助于理解的相关的题目

优先级:做题进度>学习&总结>默写回顾>做题数量

1.题目回顾

2.摆动序列(重难点) 

题目链接:376. 摆动序列 

2.1思路:

如何想到要使用贪心?

能够由局部最优→全局最优,并且举不出反例则可尝试贪心,若10分钟思路不清晰则可先跳过。

  • 贪心题目无迹可寻,若思考一会想不出来则证明挺难的,则可选择先做其他题目。

摆动→峰值数组合即最长子序列

峰值间的最长子序列就是去除中间的单调坡度,就是局部最优。

将所有峰值间中间的坡度都去掉,剩余峰值间的两端点即局部最优→全局最优。

  • 要保证两端点的位置正确性,即只在找到摆动序列时才更新上个差值点。

首元素处理

第一个元素默认为峰值,并为了判断条件一致性,为了创建新的第一段前的差值,在首部添加与首元素同值的元素,创建值为0的前段差值,便于将首个子集加入序列。

因为首个子集要加入序列,并且preDiff初始值=0,所以判断条件中preDiff要允许等于0,那么curDiff就不能等于0,否则将没有峰值→不摆动点

保证两端点的位置正确性:避免平坡bug

preDiff = curDiff要写在if判断里面,即实现前面说的只在找到摆动序列时才更新上个差值点。

preDiff = curDiff写在if判断外面,则每次自动更新preDiff,那么就会峰值间的左端点就是不断移动的,那么就无法保证当条件满足时取的是两端端点。

无法保证当前条件满足时取的是两端端点,为什么会数量有误呢? 

因为之前便于处理两端默认了初始preDiff为0,所以判断条件中允许preDiff == 0的。

那么在坡度单调变化中若出现平坡的情况

因为逻辑是每次循环都令preDiff = curDiff,此时preDiff = 0,则会导致该情况可能会被认为是峰值。

毛毛鱼老师:

“需要注意的是 0 的处理  preDiff在上一次峰值出现后为正值,而如果一直随着curDiff变化在中间就会出现0值,再次出现正数坡度时就会产生峰值计数,但摆动序列是没有出现的”

class Solution {
    public int wiggleMaxLength(int[] nums) {
        int curDiff = 0;
        int preDiff = 0;
        int count = 1;
        for(int i = 1;i < nums.length;i++){
            curDiff = nums[i] - nums[i-1];
            if((curDiff > 0 && preDiff <= 0)||(curDiff < 0 && preDiff >= 0)){
                count++;
                preDiff = curDiff;
            }
        }
        return count;
    }
}

2.最大子序和 

题目链接:53. 最大子序和 

思路

        因只需要获得最大和,不需要存储路径,所以当sum = 0时直接重新开始索引;

如果所有值都是负数的情况是否仍然适用?

  • 所以是赋值,先与sum比较大小,最后再判断是否重新开始索引。
    • 保证了若都是负值仍能够将较小的负值存储。
class Solution {
    public int maxSubArray(int[] nums) {

        int sum = 0;
        int max = nums[0];
        for(int i = 0;i < nums.length;i++){
            sum += nums[i];
            if(sum > max){
                max = sum;
            }
            // max = max > sum?max:sum;
            // max = Math.max(sum,max);
            if(sum < 0){
                sum = 0;
            }
        }  
        return max; 
    }
}

3.分发饼干 

题目链接:455.分发饼干 

class Solution {
    public int findContentChildren(int[] g, int[] s) {
        Arrays.sort(g);
        Arrays.sort(s);
        int index = 0;
        int count = 0;
        for(int i = 0;i < g.length;i++){
            while(index < s.length){
                if(s[index] >= g[i]){
                    count++;
                    index++;
                    break;
                }else{
                    index++;
                }
                
            }
        }
        return count;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值