代码随想录算法训练营29期|day31 任务以及具体安排

  •  理论基础 

    关于贪心算法,你该了解这些!

    题目分类大纲如下:

    贪心算法大纲

    #算法公开课

    《代码随想录》算法视频公开课 (opens new window)贪心算法理论基础! (opens new window),相信结合视频再看本篇题解,更有助于大家对本题的理解

    #什么是贪心

    贪心的本质是选择每一阶段的局部最优,从而达到全局最优

    这么说有点抽象,来举一个例子:

    例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿?

    指定每次拿最大的,最终结果就是拿走最大数额的钱。

    每次拿最大的就是局部最优,最后拿走最大数额的钱就是推出全局最优。

    再举一个例子如果是 有一堆盒子,你有一个背包体积为n,如何把背包尽可能装满,如果还每次选最大的盒子,就不行了。这时候就需要动态规划。动态规划的问题在下一个系列会详细讲解。

    #贪心的套路(什么时候用贪心)

    很多同学做贪心的题目的时候,想不出来是贪心,想知道有没有什么套路可以一看就看出来是贪心。

    说实话贪心算法并没有固定的套路

    所以唯一的难点就是如何通过局部最优,推出整体最优。

    那么如何能看出局部最优是否能推出整体最优呢?有没有什么固定策略或者套路呢?

    不好意思,也没有! 靠自己手动模拟,如果模拟可行,就可以试一试贪心策略,如果不可行,可能需要动态规划。

    有同学问了如何验证可不可以用贪心算法呢?

    最好用的策略就是举反例,如果想不到反例,那么就试一试贪心吧

    可有有同学认为手动模拟,举例子得出的结论不靠谱,想要严格的数学证明。

    一般数学证明有如下两种方法:

  • 数学归纳法
  • 反证法
  • 看教课书上讲解贪心可以是一堆公式,估计大家连看都不想看,所以数学证明就不在我要讲解的范围内了,大家感兴趣可以自行查找资料。

    面试中基本不会让面试者现场证明贪心的合理性,代码写出来跑过测试用例即可,或者自己能自圆其说理由就行了

    举一个不太恰当的例子:我要用一下1+1 = 2,但我要先证明1+1 为什么等于2。严谨是严谨了,但没必要。

    虽然这个例子很极端,但可以表达这么个意思:刷题或者面试的时候,手动模拟一下感觉可以局部最优推出整体最优,而且想不到反例,那么就试一试贪心

    例如刚刚举的拿钞票的例子,就是模拟一下每次拿做大的,最后就能拿到最多的钱,这还要数学证明的话,其实就不在算法面试的范围内了,可以看看专业的数学书籍!

    所以这也是为什么很多同学通过(accept)了贪心的题目,但都不知道自己用了贪心算法,因为贪心有时候就是常识性的推导,所以会认为本应该就这么做!

    那么刷题的时候什么时候真的需要数学推导呢?

    例如这道题目:链表:环找到了,那入口呢? (opens new window),这道题不用数学推导一下,就找不出环的起始位置,想试一下就不知道怎么试,这种题目确实需要数学简单推导一下。

    #贪心一般解题步骤

    贪心算法一般分为如下四步:

  • 将问题分解为若干个子问题
  • 找出适合的贪心策略
  • 求解每一个子问题的最优解
  • 将局部最优解堆叠成全局最优解
  • 这个四步其实过于理论化了,我们平时在做贪心类的题目 很难去按照这四步去思考,真是有点“鸡肋”。

    做题的时候,只要想清楚 局部最优 是什么,如果推导出全局最优,其实就够了。

    #总结

    本篇给出了什么是贪心以及大家关心的贪心算法固定套路。

    不好意思了,贪心没有套路,说白了就是常识性推导加上举反例

    最后给出贪心的一般解题步骤,大家可以发现这个解题步骤也是比较抽象的,不像是二叉树,回溯算法,给出了那么具体的解题套路和模板。

  •  455.分发饼干 
    class Solution {
        // 思路1:优先考虑饼干,小饼干先喂饱小胃口
        public int findContentChildren(int[] g, int[] s) {
            Arrays.sort(g);
            Arrays.sort(s);
            int start = 0;
            int count = 0;
            for (int i = 0; i < s.length && start < g.length; i++) {
                if (s[i] >= g[start]) {
                    start++;
                    count++;
                }
            }
            return count;
        }
    }

    思路:利用贪心算法,先用小饼干喂饱小胃口,达到局部最优,最后达到全局最优。

  •  376. 摆动序列 
    class Solution {
        public int wiggleMaxLength(int[] nums) {
            int result = 1;//把最后一个点直接加在结果里
            int pre = 0;//前面的差值
            int cur = 0;//当前的差值
            
            for(int i = 0 ; i < nums.length-1 ; i++){
                cur = nums[i+1] - nums[i];
                if(pre >= 0 && cur < 0 || pre <= 0&& cur > 0){
                    result++;
                    pre = cur;//当有坡度变化时,pre跟着cur变化,防止单调坡度有平坡的情况
                }
            }
            return result;
        }
    }

    思路:要注意三种情况(1)上下坡有平坡的情况(2)首尾元素特别考虑(3)单调坡有平坡,用pre保存前面的坡度差,用cur保存现在的坡度差。

  •  53. 最大子序和 。
    class Solution {
        public int maxSubArray(int[] nums) {
            int result = Integer.MIN_VALUE;
            int count = 0;
            for(int i = 0 ;  i < nums.length ; i++){
                count += nums[i];
                if(count > result) result = count;
                if(count < 0) count = 0;//如果小于0,起始位置相当于重新开始
            }
            return result;
        }
    }

    思路:利用局部贪心达到全局贪心,从下标为0的开始遍历,如果遍历的和<0,那么后一个加小于0的数,不如不加这个数,起始位置从当前遍历的这个数开始,达到局部贪心,如果count>result的话,赋值给result。

  • 22
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值