1. 程式人生 > 其它 >[LeetCode] 1288. Remove Covered Intervals 刪除被覆蓋區間

[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/

https://leetcode.com/problems/remove-covered-intervals/discuss/451277/JavaC%2B%2BPython-Sort-Solution


LeetCode All in One 題目講解彙總(持續更新中...)