题目描述
题目链接:435. Non-overlapping Intervals
Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.
例子
例子 1
Input: [[1,2],[2,3],[3,4],[1,3]] Output: 1 Explanation: [1,3] can be removed and the rest of intervals are non-overlapping.
例子 2
Input: [[1,2],[1,2],[1,2]] Output: 2 Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping.
例子 3
Input: [[1,2],[2,3]] Output: 0 Explanation: You don’t need to remove any of the intervals since they’re already non-overlapping.
Note
- You may assume the interval’s end point is always bigger than its start point.
- Intervals like [1,2] and [2,3] have borders “touching” but they don’t overlap each other.
解题思路
这道题首先想到是如果区间已经按首字母排好序的话,其实并不难,通过简单比较前一个区间的结束点和后一个区间的起始点是否发生重复即可;我们可以用两个变量 left
和 right
作为当前区间的左右点,当下一个区间遇到重叠时,我们需要决定舍弃哪个区间;由于题目要求希望去除越少区间(保证不重叠的情况下)越好,所以我们只需要去掉当前两个区间中结束点更远的区间即可;如果不重叠的话直接把两个点更新到下一个区间即可。另外,我们可以发现其实比较过程并不会用到当前区间的起始点,所以只需要维护一个结束点即可,代码如下:
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
if (intervals.empty()) return 0;
std::sort(intervals.begin(), intervals.end(), [](std::vector<int>& a, std::vector<int>& b) {
return a[0] < b[0];
});
int result = 0;
int right = intervals[0][1];
for (int i = 1; i < intervals.size(); i++) {
if (right > intervals[i][0]) {
result++;
right = std::min(right, intervals[i][1]);
} else {
right = intervals[i][1];
}
}
return result;
}
};
- 时间复杂度: O(nlogn)
- 空间复杂度: O(n)