leetcode贪心刷题笔记

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

  • 贪心算法⼀般分为如下四步:
  • 将问题分解为若干个问题
  • 找出适合的贪心策略
  • 求解每⼀个子问题的最优解
  • 将局部最优解堆叠成全局最优解

目录

分配问题

455发饼干

135分发糖果

区间问题

452. 用最少数量的箭引爆气球

链接:https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/
问题可以简化为贪心去除最多相互重合区间,最多去除几次能将所有区间去除
所以关键就是怎么快速找到重合的区间,可以对区间的上界或者下届进行排序
我选择的是对下界排序,标记第一个区间的上界,并计数,循环判断下一个区间的下届是否小于标记的上界,小于等于则说明重合。当不重合时,将标记上界更新为当前区间的上界,计数加一,作为新的重合区间判断标准

class Solution {
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        if (points.empty()) {
            return 0;
        }
        sort(points.begin(), points.end(), [](const vector<int>& u, const vector<int>& v) {
            return u[1] < v[1];
        });
        int pos = points[0][1];
        int ans = 1;
        for (const vector<int>& balloon: points) {
            if (balloon[0] > pos) {
                pos = balloon[1];
                ++ans;
            }
        }
        return ans;
    }
};

435. 无重叠区间

链接:https://leetcode-cn.com/problems/non-overlapping-intervals/
题目等价于 选出最多数量的区间,使得它们互不重叠,如何获得最多数量,即两个重合的区间删除其中一个后留下的区间的上界要尽可能小,因此对区间上界排序,题目也变成找不重合区间

class Solution {
public:
    int eraseOverlapIntervals(vector<vector<int>>& intervals) {
        int n=intervals.size();
        sort(intervals.begin(),intervals.end(),[](vector<int>&a,vector<int>&b){return a[1]<b[1];});
        int end=intervals[0][1];
        int ans=1;
        for(int i=1;i<n;++i){
            if(intervals[i][0]>=end){
                ans++;
                end=intervals[i][1];
            }
        }
        return n-ans;
    }
};

序列问题

两维度权衡问题

股票贪心

其他问题

605. 种花问题

链接:https://leetcode-cn.com/problems/can-place-flowers/
贪心把从头开始能种的位置全种上 种花需要考验前面位置和后面位置 通过遍历筛选前面位置可行的
很简单,从第一个位置开始遍历,为0情况就判断下一个位置不为1就种花并跳过两格,为1情况就直接跳两格。因为逢1就跳两格,所以当当前位置为0时前面方向的花位置一定没有问题,只需判断后置位是否存在问题

class Solution {
public:
    bool canPlaceFlowers(vector<int>& flowerbed, int n) {
        int f=flowerbed.size();
        if(n==0)return true;
        for(int i=0;i<f;++i){
            if(flowerbed[i]==1)++i;
            else if(i+1<f&&flowerbed[i+1]==0){
                flowerbed[i]=1;
                ++i;
                n--;
                if(n==0)return true;
            }else if(i==f-1){
                n--;
            }
        }
        return n==0;
    }
};
上一篇:435. 无重叠区间


下一篇:leetcode56.合并区间