算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和

这篇具有很好参考价值的文章主要介绍了算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基础知识

什么是贪心:贪心的本质是选择每一阶段的局部最优,从而达到全局最优。
但是贪心没有套路,做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。

455.分发饼干

很容易想到,把孩子的胃口和饼干大小都排序,都从最小值开始遍历。如果最小的饼干无法满足最小的胃口,就换到相对大一点的饼干继续测试

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        int count = 0;
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        for(int i = 0,j = 0; i < g.size() && j < s.size();){
            if(s[j] >= g[i]){
                i++;
                j++;
                count++;
            }
            else if(s[j] < g[i])j++;
        }
        return count;
    }
};

376. 摆动序列

算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和局部最优:删除单调坡度上的节点(不包括单调坡度两端的节点),那么这个坡度就可以有两个局部峰值。
整体最优:整个序列有最多的局部峰值,从而达到最长摆动序列。

核心就是上面的局部最优思路。接下来就是如何实现的问题。自己写的时候使用一个index来判断上一个是高峰还是低峰。然后将后序的值push进stack。要注意!!!一个序列如果所有值都相等,那size()==1的那个子序列可以看成只有一个峰值的摆动序列。,应该返回1而不是0。

stack 和 index实现:

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size() <= 1)return nums.size();
        if(nums.size() == 2 ){
           if(nums[0] != nums[1]) return 2;
           else return 1;
        }
        
        int index = 0;
        stack<int> st;
        int start = 1;
        st.push(nums[0]);
        for(start; start < nums.size();++start ){
            if(nums[start] == nums[0]) continue;
            if(nums[start] > nums[0]){
                index = 1;
            }
            st.push(nums[start]);
            break;
        }
        for(int i = start + 1; i < nums.size(); ++i){
            if(nums[i] > st.top() && index == 0) {
                st.push(nums[i]);
                index = 1;
            }
            else if(nums[i] < st.top() && index == 1) {
                st.push(nums[i]);
                index = 0;
            }
            else{
                st.pop();
                st.push(nums[i]);
            }
        }
        return st.size();
    }
};

卡哥的实现:
最朴素的想法,i是当前元素的下标,

prediff = nums[i] - nums[i-1],
curdiff = nums[i+1] - nums[i](prediff > 0 && curdiff < 0) || (prediff < 0 && curdiff > 0)
res加一

但是一个序列会有多种情况

  • 情况一:上下坡中有平坡
    算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和
    在图中,当i指向第一个2的时候,prediff > 0 && curdiff = 0 ,当 i 指向最后一个2的时候 prediff = 0 && curdiff < 0。
    如果我们采用,删左面三个2的规则,那么 当 prediff = 0 && curdiff < 0 也要记录一个峰值,因为他是把之前相同的元素都删掉留下的峰值。
    所以我们记录峰值的条件应该是: (preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0),为什么这里允许 prediff == 0 ,就是为了 上面我说的这种情况。

  • 情况二:数组首尾两端
    首先,不管这个数组的大小是多少,只要大于等于2,就至少有一个大小为1的子序列,能够成为一个摆动序列。所以一开始res就被设置为1。在遍历数组的时候,i= 0开始, 因为要计算 curdiff = nums[i+1] - nums[i]; i < nums.size()-1。这意味着数组尾元素不会被遍历,但是没关系,res设置为1就是默认数组尾端是一个峰值。

下面看两种情况处理首元素:
1、[2,5]
算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和针对序列[2,5],可以假设为[2,2,5],这样它就有坡度了即preDiff = 0。针对以上情形,result初始为1(默认最右面有一个峰值),此时curDiff > 0 && preDiff <= 0,那么result++(计算了左面的峰值),最后得到的result就是2(峰值个数为2即摆动序列长度为2)
2、[2,2]
这种情况其实就是平坡,index = 0 的地方 curDiff = prediff = 0不会统计。只到index = 1不会被遍历到,但是已经在最开始作为默认峰值统计到res中。

  • 情况三:单调坡度有平坡
    算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和上述情况会被统计三次。所以pre应当在有波动的时候才被更新。否则就保持原有的pre
    算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        if(nums.size() <= 1) return nums.size();
        int preDiff = 0;
        int curDiff = 0;
        int res = 1;
        for(int i = 0 ; i < nums.size()-1; ++i){
            curDiff = nums[i+1] - nums[i];
            if((preDiff<=0 && curDiff>0) || (preDiff>=0 && curDiff<0)){
                res++;
                preDiff = curDiff;
            }
        }
        return res;
    }
};

53. 最大子数组和

暴力解法: 两层for循环,计算每一个子数组的和,记录最大值。

贪心:如果 -2 1 在一起,计算起点的时候,一定是从1开始计算,因为负数只会拉低总和,这就是贪心贪的地方!

局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。比如有元素 abcd,如果a+b>=0,a+b+c<0,那么无论ab取多少,只要取到c整体和就是一个负数。负数加上任何一个数,不管是正负还是0,都只会更小。
-5 + (-1) = -6
-1 + (-5) = -6。
-5 + 1 = -4

全局最优:选取最大“连续和”
局部最优的情况下,并记录最大的“连续和”,可以推出全局最优。
其关键在于:不能让“连续和”为负数的时候加上下一个元素,而不是 不让“连续和”加上一个负数。文章来源地址https://www.toymoban.com/news/detail-415074.html

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int sum = 0;
        int res = INT_MIN;
        for(int i = 0; i < nums.size(); ++i){
            sum += nums[i];
            if (sum > res) res = sum;
            if(sum < 0) sum = 0;
        }
        return res;
    }
};

到了这里,关于算法 贪心1 || 455.分发饼干 376. 摆动序列 53. 最大子数组和的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法刷题Day 31 分发饼干+摆动序列+最大子序列和

    分发饼干其实有很多种写法,但是下面这种贪心的解法是最好理解,也最好解释的 我的其他解法 贪心算法 这道题用贪心算法要考虑的细节有很多。 动态规划 有点难(甚至涉及到了线段树),等后面二刷的时候再来学好了 暴力解法 超时了 贪心算法 贪心算法的代码写起来简

    2024年02月15日
    浏览(45)
  • LeetCode:455. 分发饼干——贪心算法

    🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀 算法专栏: 👉🏻123 贪心算法是在每个阶段选取 局部 最优解,最终得到 全局最优解 的一种思想。贪心算法与动态规划的思路相似,但贪心算法要在每个阶段选择最优解,而这个最优解不一定是全局最优解

    2023年04月15日
    浏览(38)
  • LeetCode-455-分发饼干-贪心算法

    题目描述: 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] = g[i],我们可以将这个饼干 j 分配

    2024年02月10日
    浏览(41)
  • leetCode 376.摆动序列 贪心算法

    如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为  摆动序列 。 第一个差(如果存在的话)可能是正数或负数。 仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如,  [1, 7, 4, 9, 2, 5]  是一个  摆动序列  ,因为差值  (6, -3, 5, -7, 3)  是正负

    2024年02月07日
    浏览(39)
  • LeetCode:376. 摆动序列——说什么贪心和动规~

    🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀 算法专栏: 👉🏻123 题目描述 :如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也

    2024年02月03日
    浏览(40)
  • 分发饼干【贪心算法】

    分发饼干 假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] = g[i],我们可以将这个饼干 j 分配给

    2024年02月11日
    浏览(33)
  • 455. 分发饼干 - 力扣(LeetCode)

    假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。 对每个孩子 i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干 j,都有一个尺寸 s[j] 。如果 s[j] = g[i],我们可以将这个饼干 j 分配给孩子 i ,这

    2024年01月25日
    浏览(47)
  • LeetCode(力扣)455. 分发饼干Python

    https://leetcode.cn/problems/assign-cookies/ 从大遍历 从小遍历

    2024年02月09日
    浏览(36)
  • 【经典LeetCode算法题目专栏分类】【第5期】贪心算法:分发饼干、跳跃游戏、模拟行走机器人

    《博主简介》 小伙伴们好,我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌ 更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍 感谢小伙伴 们点赞、关注! class   Solution :      def   findContentChildren ( self ,  g :  List [ int ],  s

    2024年02月04日
    浏览(55)
  • 算法题:摆动序列(贪心算法解决序列问题)

    这道题是一道贪心算法题,如果前两个数是递增,则后面要递减,如果不符合则往后遍历,直到找到符合的。(完整题目附在了最后) 代码如下: 完整题目: 376. 摆动序列 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为  摆动序列 。 第一个差(如果

    2024年02月07日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包