开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 28 天,点击查看活动详情
题目:LeetCode
给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
示例 1:
输入: intervals = [[1,2],[2,3],[3,4],[1,3]]
输出: 1
解释: 移除 [1,3] 后,剩下的区间没有重叠。
示例 2:
输入: intervals = [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
示例 3:
输入: intervals = [ [1,2], [2,3] ]
输出: 0
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
提示:
intervals[i].length == 2
解题思路
根据题意可知将区间按照起点从大到小进行排序 以当前区间为基础,判断其与下个区间是否有交集
- 如果有交集,那么就应该删除其中一个区间,所以count++ 应该删除哪个区间呢?
- 应该删除两个区间中较长的区间,所以我们将两个区间的右边界设置为较小的右边界,形式上的将较长区间缩短了
- 另外,重要点在于首先按照起点大小排序,这样左边界永远递增,省去了对左边界的判断
通过顺序遍历的方式,即可拿到上一个区间的范围。 如果当前区间在上一个区间内,我们对当前区间的结束下标记录为上一个区间的结束下标,同时进行计数即可。
代码实现
public int eraseOverlapIntervals(int[][] intervals) {
// 按照区间起点从大到小排序
Arrays.sort(intervals, new Comparator < int[] > () {
public int compare(int[] nums1, int[] nums2) {
return nums1[0] - nums2[0];
}
});
int count = 0;
for (int i = 0; i < intervals.length - 1; i++) {
if (intervals[i][1] > intervals[i + 1][0]) {
count++;
int val = Math.min(intervals[i][1], intervals[i + 1][1]);
intervals[i][1] = val;
intervals[i + 1][1] = val;
}
}
return count;
}
运行结果
复杂度分析
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN) 一起分享知识, Keep Learning!