問題

給定一些區間 intervals[i], intervals[i][0] 為左邊界, intervals[i][1] 為右邊界
找出一個整數集合 S, 使得任意一個 intervals[i] 與 S 相交的個數至少為 2


構想

先將 intervals 排序, 由於我們希望在選兩個重疊的點的時候能夠重複利用
所以我們以右邊界來排序, 如果右邊界相等, 那麼左邊界較右邊的排在前面

假設兩個點 left 與 right 與 intervals[i] 相交
在檢查 intervals[i+1] 時

  • left 大於等於 intervals[i+1] 的左邊界, 意味著 right 也在 intervals[i+1] 的區間裡
  • left 小於 intervals[i+1] 的左邊界, 但是 right 大於等於 intervals[i+1] 的左邊界, 代表左邊界要重選, 並解將 left 放進 S 裡
  • left 與 right 都小於 itnervals[i+1] 的左邊界, 代表 left 與 right 都要重選, 並將 left 與 right 放進 S 裡

在重選時, 由於區間已排序過, 選擇區間的右邊界是保險的作法


大专栏  leetcode 757>解法

class Solution {
public:
    int intersectionSizeTwo(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end(), [](vector<int> &a, vector<int> &b) {
            if (a[1] < b[1]) {
                return true;
            } else if (a[1] == b[1] && a[0] > b[0]) {
                return true;
            } else {
                return false;
            }
        });
        int n = intervals.size();
        int ret = 0;
        int left = -1, right = -1;
        for (int i=0; i<n; i++) {
            if (intervals[i][0] > left) {
                if (intervals[i][0] > right) {
                    ret += 2;
                    right = intervals[i][1];
                    left = right - 1;
                } else {
                    ret ++;
                    left = right;
                    right = intervals[i][1];
                }
            }
        }
        return ret;
    }
};


分析

40ms 100% beat
time complexity: O(nlogn)

01-14 20:09