1.題目介紹
題目地址(435. 無重疊區間 - 力扣(LeetCode))
https://leetcode.cn/problems/non-overlapping-intervals/
題目描述
給定一個區間的集合 intervals
,其中 intervals[i] = [starti, endi]
。返回 需要移除區間的最小數量,使剩餘區間互不重疊 。
示例 1:
輸入: intervals = [[1,2],[2,3],[3,4],[1,3]] 輸出: 1 解釋: 移除 [1,3] 後,剩下的區間沒有重疊。
示例 2:
輸入: intervals = [ [1,2], [1,2], [1,2] ] 輸出: 2 解釋: 你需要移除兩個 [1,2] 來使剩下的區間沒有重疊。
示例 3:
輸入: intervals = [ [1,2], [2,3] ] 輸出: 0 解釋: 你不需要移除任何區間,因為它們已經是無重疊的了。
提示:
1 <= intervals.length <= 105
intervals[i].length == 2
-5 * 104 <= starti < endi <= 5 * 104
2.題解
2.1 貪心演算法
思路
見貪心演算法講解-區間排程問題
這一題是一個典型的區間排程問題,移出區間的最小數量,換句話說就是在有限區間內,儘可能多的安排任務,求最大安排任務數量
我們有著幾種貪心策略:
1.最早開始時間(很明顯不行,最早開始,但是長度覆蓋過大,就會導致移除區間數量過多)
2.最早結束時間(區間排程問題的核心策略,從左往右遍歷時,更早結束的時間,可以空餘出更大的選擇空間,就可以更大可能選擇更多的區間)
3.最短耗時(並不一定,假設卡在兩個區間之間就bong!了)
程式碼
class Solution {
public:
static bool compare(vector<int> n1 , vector<int> n2){
return n1[1] < n2[1];
}
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), compare);
int i = 1, cnt = 0, n = intervals.size(), endTime = intervals[0][1];
while(i < n){
if(endTime > intervals[i][0]){
cnt++;
}else{
endTime = intervals[i][1];
}
i++;
}
return cnt;
}
};
複雜度分析
令 n 為陣列長度。
- 時間複雜度:\(O(n)\)
- 空間複雜度:\(O(n)\)