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;
}
};