LeetCode | C++ 贪心算法——理论基础、455.分发饼干、376. 摆动序列、53. 最大子序和

52 篇文章 0 订阅
文章介绍了贪心算法的基本思想,即通过每一步选择局部最优来达到全局最优。分别展示了如何使用贪心策略解决455.分发饼干(按大小匹配)、376.摆动序列(识别上下坡序列)和53.最大子序和(寻找连续子数组的最大和)这三个问题。每个问题都提供了具体的解题步骤和代码实现。
摘要由CSDN通过智能技术生成

理论基础

贪心算法其实就是没有什么规律可言

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

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

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

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

贪心一般解题步骤:分为如下四步:

  • 将问题分解为若干个子问题
  • 找出适合的贪心策略
  • 求解每一个子问题的最优解
  • 将局部最优解堆叠成全局最优解

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

455.分发饼干

思路:用小饼干尽量先去满足胃口小的孩子,或者用大饼干尽量先去满足胃口大的孩子

对孩子的胃口,和饼干进行排序

遍历的时候,一定是先遍历孩子,再遍历饼干,因为如果饼干不能满足条件的话,是不能一直 减减的

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        int result = 0;
        int index = s.size() - 1;
        // 利用大饼干先去满足大胃口的孩子
        for (int i = g.size() - 1; i >= 0; i--) {
            if (index >= 0 && s[index] >= g[i]) {
                index--;
                result++;    
            }
        }
        return result;
    }
};

376. 摆动序列

本题需要考虑三种情况

  1. 上下坡中有平坡 算1个
  2. 数组首尾两端
  3. 单调坡中有平坡 不算

默认第一个值前面有一个相同的值,产生平坡, prediff = 0, 将数组首考虑进来,result 默认为1, 将 数组尾考虑进来

最后当坡度变化时再将 prediff 变为 curdiff 将两种平坡的情况考虑进来

class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int result = 1;
        int prediff = 0;
        int curdiff = 0;
        for (int i = 0; i < nums.size() - 1; i++) {
            curdiff = nums[i + 1] - nums[i];
            if (prediff >= 0 && curdiff < 0 || prediff <= 0 && curdiff > 0) {
                result++;
                prediff = curdiff;
            } 
        }
        return result;
    }
};

53. 最大子序和

局部最优:当前“连续和”为负数的时候立刻放弃,从下一个元素重新计算“连续和”,因为负数加上下一个元素 “连续和”只会越来越小。

全局最优:选取最大“连续和”

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result = INT32_MIN;
        int tmp = 0;
        for (int i = 0; i < nums.size(); i++) {
            tmp += nums[i];
            result = result < tmp ? tmp : result;
            if (tmp < 0) tmp = 0;
        }
        return result;
    }
};

参考:
卡哥代码随想录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值