Greedy(一) Interval 专题

60 阅读3分钟

前言:

Greedy Algorithm. Solving an optimization problem. Wouldn't it be great to solve optimization problems witout using dynamic programming and solving all those subproblems?

"什么是贪心算法呢?
贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多的条件(贪心选择性质),但是效率比动态规划要高。
比如说一个算法问题使用暴力解法需要指数级时间,如果能使用动态规划消除重叠子问题,就可以降到多项式级别的时间,如果满足贪心选择性质,那么可以进一步降低时间复杂度,达到线性级别的。

什么是贪心选择性质呢?
简单说就是:每一步都做出一个局部最优的选择,最终的结果就是全局最优。注意哦,这是一种特殊性质,其实只有一部分问题拥有这个性质。
比如你面前放着 100 张人民币,你只能拿十张,怎么才能拿最多的面额?显然每次选择剩下钞票中面值最大的一张,最后你的选择一定是最优的。

然而,大部分问题明显不具有贪心选择性质。比如打斗地主,对手出对儿三,按照贪心策略,你应该出尽可能小的牌刚好压制住对方,但现实情况我们甚至可能会出王炸。这种情况就不能用贪心算法,而得使用动态规划解决,参见「动态规划解决博弈问题」。 作者:一个人的世界_8575
链接:www.jianshu.com/p/46628652f…

课堂案例 区间调度问题

6033 Linda Sellie Course example Interval Scheduling Problem区间调度问题

image.png

这个问题很有趣的一点是(Dong Li在课堂上问的问题): Will the earliest finishing time method and Latest starting time method(from end to start) yield different result? The answer is: Both approaches can theoretically yield the same number of maximum non-overlapping intervals under ideal conditions. But the intervals they choose is different.

How do we code this up? image.png

有俩个array,我们要keep track of two arrays

实战精选:

以下一天内做完

image.png

这道题可以引生很多Leetcode 经典Interval questions

435. Non-overlapping Intervals
因为Leetcode中最后需要的东西和老师给的例题不太一样,所以我们可以简化空间复杂度

452. Minimum Number of Arrows to Burst Balloons

其他interval问题:

阅读

力扣 面试高频区间调度类问题总结 interval scheduling

Intervals向来是高频考点题,Google、华为等大公司都喜欢面试考Interval,但其实内核还挺简单的,在这里顺便做一下挺好的。

Leetcode

252. Meeting Rooms easy 题,做完上面俩道题之后自然思路会非常清晰

56. Merge Intervals 和上面的思路微微有点不太一样但做完上面的题动动脑就会明白的题 面试出现28次

57. Insert Interval

253. Meeting Rooms II 这道题真不错,因为第一时间我没想出来。也可能是做到这里做累了 脑子转不动了。 第一遍没做对的答案: 原思路: sort by finishing time, 如果重叠 count++,

class Solution {
public:
    int minMeetingRooms(vector<vector<int>>& intervals) {
        if(intervals.size() == 1) return 1;
        sort(intervals.begin(), intervals.end(), [](const vector<int>& a, const vector<int>& b){
            return a[1] < b[1];
        });
        
        int start = intervals[0][0], end = intervals[0][1];
        int count = 1;
        for(int i = 1; i < intervals.size(); i++){
            if(intervals[i][0] >= end) {
                start = intervals[i][0];
                end = intervals[i][1];
            } else{
                count++;
            }
        }
        return count;
    }
};

做不出来的原因是这个Interval的解不是单纯的Greedy 而是用min Heap去解的答案。

视频讲解 b站 一姐

这个自己真的要尝试自己讲一遍题。

1288. Remove Covered Intervals