问题:
给定一组[start, end]的区间数组,求其间最少去掉多少个区间,可使得剩下的区间互不重叠。
⚠️ 注意:[1,2][2,3]这样:前一个区间end=后一个区间start,的两个区间也不重叠。
Example 1: Input: [[1,2],[2,3],[3,4],[1,3]] Output: 1 Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. Example 2: Input: [[1,2],[1,2],[1,2]] Output: 2 Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. Example 3: Input: [[1,2],[2,3]] Output: 0 Explanation: You don't need to remove any of the intervals since they're already non-overlapping. Note: You may assume the interval's end point is always bigger than its start point. Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other.
解法:Greedy(DP+条件<每个子问题的最优解可导致最终最优解>)
DP:由于各个子问题之间可能会互相影响,因此可能是几个子问题的最优解->问题整体的最优解。
而Greedy:则一定可由每个子问题的最优解->问题整体的最优解。(条件略比DP更加严苛)
本问题,求最少去掉几个区间,使得留下的区间互不重叠。
-> 即,要使得留下最多多少个互不重叠的区间。
子问题:每个区间的start要>=上一个区间的end
最优情况:我们要使能留下更多的区间->留下的每个区间尽可能end的早。
1. 因此,我们对所有区间,根据end进行排序。
尽量选取排在前面的区间,这样,我们选取的区间,都是尽可能end早的区间,
留下的空余选择空间就更长,更有利于选择更多区间。
2. 然后,遍历排过序的区间。
若start>=前一个选择区间的end,那么该区间入选(该区间end是目前待选区间中最早的。)入选区间数count++
3. 最后,得到的count数,则为留下的最多互不重叠的区间数。
那么要求的去掉最少多少个区间数=总区间数-count
代码参考:
1 class Solution { 2 public: 3 //Greedy: 4 //find the [earliest ended] interval-> can get the most number of non-overlapping intervals. 5 bool static cmp(vector<int> a, vector<int> b) { 6 return a[1]<b[1]; 7 } 8 int eraseOverlapIntervals(vector<vector<int>>& intervals) { 9 int count=1; 10 if(intervals.size()==0) return 0; 11 //sort the intervals by end bound 12 sort(intervals.begin(), intervals.end(), cmp); 13 int pre_end = intervals[0][1]; 14 int cur_start; 15 for(vector<int> itv:intervals) { 16 cur_start = itv[0]; 17 if(cur_start >= pre_end){ 18 count++; 19 pre_end = itv[1]; 20 } 21 } 22 return intervals.size() - count; 23 } 24 };