代码随想录Day31 | 贪心算法 455.分发饼干 376. 摆动序列 53. 最大子序和

代码随想录Day31 | 贪心算法 455.分发饼干 376. 摆动序列 53. 最大子序和

贪心算法

局部最佳 --> 全局最佳
刷题或者面试的时候,手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心

455.分发饼干

文档讲解:代码随想录
视频讲解: 贪心算法,你想先喂哪个小孩?| LeetCode:455.分发饼干
状态

局部最优:有两种思考方式,最大的饼干喂饱最大胃口 或则 最小的饼干去喂饱最小的胃口,其实道理都是一样的
但是遍历的是饼干还是胃口就有区别了。
先满足最大的,需要通过胃口的遍历来控制饼干的移动。
先满足最小的,需要通过饼干的遍历来控制胃口的移动。
在这里插入图片描述

由于需要从最小开始或则最大开始所以需要对两个数组排序。排序之后,对于当前的饼干最大值去寻找满足条件的最大胃口,然后移动两个指针直到一个指针走完了其所属的数组

//对于满足
//优先满足能够满足的最大胃口的孩子

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        int res = 0;
        if(g.size() == 0 || s.size() == 0)
        {
            return res;
        }
        //对孩子的胃口排序
        sort(g.begin(),g.end());
        //对饼干的大小排序
        sort(s.begin(),s.end());
        //对s从大到小,去考察g中的大小
        int i = s.size()-1;
        //遍历胃口,当有胃口合适的计数
        for(int j = g.size()-1;j>=0;j--)
        {
            if(i>=0 && g[j] <= s[i])
            {
                res++;
                i--;
            }
        }
        return res;
    }
};

376.摆动序列

文档讲解:代码随想录
视频讲解: 贪心算法,寻找摆动有细节!| LeetCode:376.摆动序列
状态

局部最优:删除单调走向上的节点,或者平坡的节点 --> 保留峰和谷

情况一:上下坡中有平坡
情况二:数组首尾两端
情况三: 单调坡中有平坡

在这里插入图片描述
pre应当在更新坡度时才改变,即放到if语句里面,否则实时更新pre那么,平坡会消除单调性,导致判断失误

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size() <= 1)
        {
            return nums.size();
        }
        int res = 1;

        //当前的差值
        int cur = 0;
        //前一步的差值
        int pre = 0;

        for(int i = 0;i<nums.size()-1;i++)
        {
            cur = nums[i+1] - nums[i];
            if(cur < 0 && pre >= 0)
            {   
                res++;
                pre = cur;
            }
            if(cur > 0 && pre <= 0)
            {
                res++;
                pre = cur;
            }
        }
        return res;
    }
};

53.最大子序和

文档讲解:代码随想录
视频讲解: 贪心算法的巧妙需要慢慢体会!LeetCode:53. 最大子序和
状态

局部最优:当当前和计算为负数时,就需要放弃,因为其会导致下一个连续和变小。
代码随想录中这个关于是负数还是和为负数更新位置的解释很清晰
在这里插入图片描述

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        //记录返回和
        int res = INT_MIN;

        //记录当前序列和
        int cur = 0;
        for(int i = 0;i<nums.size();i++)
        {
            //记录当前下标以及之前的和
            cur += nums[i];
            if(cur > res)
            {
                res = cur;
            }
            //如果和为负数,那么清空cur相当于从下一个数再重新开始计算
            if(cur <  0)
            {
                cur = 0;
            }
        }
        
        return res;
    }
};
上一篇: 代码随想录Day30 | 332.重新安排行程 51. N皇后 37. 解数独
下一篇: 代码随想录Day32 | 122.买卖股票的最佳时机II 55. 跳跃游戏 45.跳跃游戏II
sRiddle
博客等级 码龄7年 528粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值