Day31 贪心算法 LeetCode 455 376 53

156 阅读1分钟

理论基础

  • 局部最优推出全局最优即可,没有技巧,模拟为主,多想反例
  • 贪心无套路,要么简单要么很难,5分钟没思路,立刻看题解

455. 分发饼干

心得

  • 双层循环考虑复杂了,只需要一次层从一边遍历即可

题解

  • 优先满足大饼干供应大孩子,如果小饼干优先满足小孩子则外循环正好相反
  • 单边按序遍历,即可节省内层循环
class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        if (s.size() == 0) return 0;
        sort(g.begin(), g.end());
        sort(s.begin(), s.end());
        int count = 0;
        int index = s.size() - 1;
        for (int i = g.size() - 1; i >= 0; i--) { // 注意大的先满足
            if (index >=0 && g[i] <= s[index]) {
                count++;
                index--;
            }
        }
        return count;
    }
};

376. 摆动序列

心得

  • 只是统计长度不需要真的删除数组元素,画出示意图了解两种平坡和虚拟起始点概念,遍历的其实位置是为了代码简洁性考虑

题解

  • 两种平坡时候的判断,注意改变前一个变化的位置
class Solution {
public:
    int wiggleMaxLength(vector<int>& nums) {
        int curDiff = 0; // 当前变化
        int prevDiff = 0; // 之前变化
        int result = 1;
        if (nums.size() == 1) return result;
        for (int i = 0; i < nums.size() - 1; i++) {
            curDiff = nums[i + 1] - nums[i];
            if ((prevDiff >= 0 && curDiff < 0) || (prevDiff <= 0 && curDiff > 0)) {
                result++;
                prevDiff = curDiff; // 仅仅在发生摆动变化时,改变调性
            } 
        }
        return result;
    }
};

53. 最大子数组和

心得

  • 混用动规和贪心,导致混乱

题解

  • 贪心贪的是前面连续求和大于0才能对后面的值增加有正效益
class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int result = INT_MIN;
        int count = 0; 
        for (int i = 0; i < nums.size(); i++) {
            count += nums[i];
            if (count > result) result = count; // 当前累加高于最值,记录
            if (count <= 0) count = 0; // 累加和小于0 没有正效益
        }
        return result;
    }
};