1. 程式人生 > 實用技巧 >[LintCode 1668.] 區間最小覆蓋

[LintCode 1668.] 區間最小覆蓋

1668. 區間最小覆蓋
CAT 專屬題目

數軸上有 n 個區間. 現在需要在數軸上選取一些點, 使得任意一個區間內至少包含一個點.

返回最少選取的點的數目.

樣例
樣例 1:

輸入: [(1,5), (4,8), (10,12)]
輸出: 2
解釋:
選擇兩個點: 5, 10
第一個區間 [1, 5] 包含了 5
第二個區間 [4, 8] 包含了 5
第三個區間 [10, 12] 包含了 10
樣例 2:

輸入: [(1,5), (4,8), (5,12)]
輸出: 1
解釋: 所有區間都包含 5
注意事項

  1. 1 <= n <= 10^4
  2. 保證給定的區間合法, 且區間左右端點在[0, 10^5] 範圍內
  3. 給定的都是閉區間

按照開始時間排序選結束時間點,會漏掉開始晚結束早的。比如[(1,4),(2,3),(4,6)],按開始時間排序後,第一次選的是4,跳過第二個區間,判斷第三個區間也能覆蓋,得到答案為1。實際上第二個區間被忽視了,4這個點並不能覆蓋(2,3)這個區間。
按照結束時間排序選結束時間點就沒問題了。

/**
 * Definition of Interval:
 * classs Interval {
 *     int start, end;
 *     Interval(int start, int end) {
 *         this->start = start;
 *         this->end = end;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param a: the array a
     * @return: return the minimal points number
     */
    int getAns(vector<Interval> &a) {
        // write your code here
        if (a.empty()) return 0;
        std::sort(a.begin(), a.end(), cmp);
        int res = 1;
        int selected = a[0].end;
        for (int i=1; i<a.size(); i++) {
            if (a[i].start <= selected) continue;
            else {
                selected = a[i].end;
                res++;
            }
        }
        return res;
    }
    static bool cmp(const Interval& lhs, const Interval& rhs) {
        if (lhs.end != rhs.end)
            return lhs.end < rhs.end;
        return lhs.start < rhs.start;
    }
};