[LeetCode] 1288. Remove Covered Intervals 刪除被覆蓋區間
Given an array intervals
where intervals[i] = [li, ri]
represent the interval [li, ri)
, remove all intervals that are covered by another interval in the list.
The interval [a, b)
is covered by the interval [c, d)
if and only if c <= a
and b <= d
.
Return the number of remaining intervals.
Example 1:
Input: intervals = [[1,4],[3,6],[2,8]]
Output: 2
Explanation: Interval [3,6] is covered by [2,8], therefore it is removed.
Example 2:
Input: intervals = [[1,4],[2,3]]
Output: 1
Constraints:
1 <= intervals.length <= 1000
intervals[i].length == 2
0 <= li < ri <= 105
- All the given intervals are unique.
這道題給了我們一個區間陣列,說是讓移除所有被完全包含的區間,比如區間 [3, 6] 就是完全包含在區間 [2, 8] 中的,注意這裡完全相同的兩個區間也可以算是包含關係。當然最簡單粗暴的方法就是對於每個區間,都遍歷其他所有的區間,看是否包含或者被包含,但這種方法太不高效,估計過不了 OJ,所以博主試都沒試。得想一想有沒有什麼簡便的方法,由於一個區間要被另一個區間包含,那麼小區間的左邊界要大一些,右邊界要小一些,所以如果按左邊界排序,則後面的區間更容易被前面的區間包含。排序後的陣列,當前區間的左邊界一定是不小於前面區間的左邊界的,所以只要比較右邊界,若當前區間的右邊界小於等於前面任意一個區間的右邊界的話,則當前的區間一定是被包括的,所以需要統計前面區間中的最大右邊界。被包括的區間就不用計數了,那麼反過來,不被包括的時候,res 就要自增1。若當前區間的右邊界大於前面區間的最大右邊界,且當前區間的左邊界大於之前最大右邊界區間的左邊界時,當前區間不會包括或被包括於任何區間,此時 res 要自增1,而且 left 要更新為當前的左邊界,每次遍歷完一個區間後,都用該區間的右邊界來更新 right 即可,參見程式碼如下:
class Solution {
public:
int removeCoveredIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end());
int res = 1, n = intervals.size(), left = intervals[0][0], right = intervals[0][1];
for (int i = 1; i < n; ++i) {
if (intervals[i][0] > left && intervals[i][1] > right) {
left = intervals[i][0];
++res;
}
right = max(right, intervals[i][1]);
}
return res;
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/1288
參考資料:
https://leetcode.com/problems/remove-covered-intervals/