1288. Remove Covered Intervals**
https://leetcode.com/problems/remove-covered-intervals/
題目描述
Given a list of intervals, remove all intervals that are covered by another interval in the list. Interval [a,b)
is covered by interval [c,d)
if and only if c <= a
and b <= d
.
After doing so, 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.
Constraints:
1 <= intervals.length <= 1000
0 <= intervals[i][0] < intervals[i][1] <= 10^5
intervals[i] != intervals[j] for all i != j
C++ 實現 1
使用最大堆. 對於區間 p = [x, y)
, 將 y
值較大的放到堆頂, 如果 y
值相等, 那麼將 x
值較小的放到堆頂. 使得堆頂的那個區間是覆蓋面最大的.
class Solution {
private:
struct Comp {
bool operator()(const vector<int> &p, const vector<int> &q) {
return (p[1] < q[1]) || ((p[1] == q[1]) && (p[0] > q[0]));
}
};
public:
int removeCoveredIntervals(vector<vector<int>>& intervals) {
priority_queue<vector<int>, vector<vector<int>>, Comp> q;
for (auto &v : intervals) q.push(v);
int res = 0;
while (!q.empty()) {
auto n = q.top();
q.pop();
res ++;
// 之後只需要判斷堆頂的元素能覆蓋多少其他區間
while (!q.empty() && n[0] <= q.top()[0]) q.pop();
}
return res;
}
};
C++ 實現 2
排序的做法. 對於區間 p = [x, y)
, 將 x
較小的排在前面, 如果 x
相等, 則將 y
較大的排在前面. 這樣相當於固定了 x
的下限, 之後只需要用 ma
來記錄上一個覆蓋面最大的區間的 y
值, 對於當前訪問的區間 v
, 它的 x
值肯定小於或等於上一個覆蓋面最大的區間的 x
值, 因此只需要判斷 v
的 y
值是否更大, 如果是的話, 說明沒有被上一個區間覆蓋.
class Solution {
public:
int removeCoveredIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(), [](const vector<int> &v1, const vector<int> &v2)->bool {
if (v1[0] == v2[0])
return v1[1] > v2[1];
return v1[0] < v2[0];
});
int ma = INT_MIN, res = 0;
for (vector<int> v : intervals) {
if (v[1] > ma) {
res++;
ma = v[1];
}
}
return res;
}
};