LeetCode練習題435. Non-overlapping Intervals
阿新 • • 發佈:2018-12-18
題目
Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals 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.
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.
分析
原題是讓我們去除有重疊的區間,以使得剩下的區間之間不存在重疊。問最少需要去除多少個這樣的區間。
這道題是典型的用貪心演算法來求解的問題,而難點在於如何找到一個正確的貪心演算法。
我一開始是用以下貪心演算法求解的:每遍歷一次所有的區間,就找出這樣一個區間,與該區間重疊的區間數量最多,然後去除該區間,一直迴圈遍歷重複之前步驟直到剩餘區間沒有重疊的。最後按照該方法計算得到的結果並不正確,所以要憑空找到正確的貪心演算法並不容易。
正確做法如下:
設想這樣的情景:我們要完成一些任務,這些任務都有它自己的完成所需的時間區間,完成任務所需的時間區間有可能重疊,然而我們在一個時間區間內只能執行一個任務。所以為了儘可能的完成更多的任務,我們要選擇執行結束時間更早的任務,這樣在一定的時間區間內,我們才能完成更多的任務。
這道題也類似,我們要選擇結束時間更早的區間,並且這些區間沒有衝突,然後剩餘沒有被選擇的區間就是要被去除的。
通過這道題我們發現,要解決貪心問題,關鍵在於找到一個合適並且正確的貪心演算法,然而有時候查詢這樣的貪心演算法並不容易,這需要我們經過大量的練習積累經驗,這樣才能更好地應對這類貪心問題。
程式碼
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
class Solution {
public:
static bool mySortFun(Interval a, Interval b) {
if (a.end != b.end) {
return a.end < b.end;
}
else {
return a.start < b.start;
}
}
//這是一個貪心問題,我們每次都找到那個結束點最小的區間,
//然後依次向後找那些與前面區間不衝突且結束點早的區間。
//這個過程中我們把區域性的最優解合併成了全域性的最優解
int eraseOverlapIntervals(vector<Interval>& intervals) {
if (intervals.size() <= 1) return 0;
int head;
int result = 0;
sort(intervals.begin(), intervals.end(), mySortFun);
head = intervals.front().end;
for (int i = 1; i < intervals.size(); i++) {
if (intervals[i].start < head) {
result++;
}
else {
head = intervals[i].end;
}
}
return result;
}
};