无重叠区间
难度:
标签:
题目描述
给定一个区间的集合 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 解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
提示:
1 <= intervals.length <= 105
intervals[i].length == 2
-5 * 104 <= starti < endi <= 5 * 104
代码结果
运行时间: 126 ms, 内存: 46.9 MB
/*
* 思路:
* 1. 首先将区间按照结束时间进行排序。
* 2. 使用贪心算法,从第一个区间开始选择,每次选择结束时间最早且不与前一个选择的区间重叠的区间。
* 3. 计算需要移除的区间数量。
*/
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
// 按照区间的结束时间进行排序
List<int[]> sortedIntervals = Arrays.stream(intervals)
.sorted((a, b) -> Integer.compare(a[1], b[1]))
.collect(Collectors.toList());
int count = 0;
int end = sortedIntervals.get(0)[1];
for (int i = 1; i < sortedIntervals.size(); i++) {
if (sortedIntervals.get(i)[0] < end) {
// 当前区间与前一个区间重叠,计数加一
count++;
} else {
// 更新结束时间
end = sortedIntervals.get(i)[1];
}
}
return count;
}
}
解释
方法:
该题解的思路是贪心算法。首先将区间按照结束时间从小到大排序。然后从第一个区间开始,初始化一个计数器 ans 为1,表示至少有一个不重叠的区间。同时用一个变量 right 记录当前选择区间的结束时间。遍历后面的区间,如果当前区间的开始时间小于 right,说明有重叠,跳过该区间;否则,将 right 更新为当前区间的结束时间,ans 加1。最后用区间总数减去 ans,即为需要移除的最小区间数。
时间复杂度:
O(nlogn)
空间复杂度:
O(n)
代码细节讲解
🦆
在贪心选择法中,初始化 ans 为 1 代表什么意义,这是否意味着至少有一个区间不需要移除?
▷相关问题
用最少数量的箭引爆气球
有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points
,其中points[i] = [xstart, xend]
表示水平直径在 xstart
和 xend
之间的气球。你不知道气球的确切 y 坐标。
一支弓箭可以沿着 x 轴从不同点 完全垂直 地射出。在坐标 x
处射出一支箭,若有一个气球的直径的开始和结束坐标为 x
start
,x
end
, 且满足 xstart ≤ x ≤ x
end
,则该气球会被 引爆 。可以射出的弓箭的数量 没有限制 。 弓箭一旦被射出之后,可以无限地前进。
给你一个数组 points
,返回引爆所有气球所必须射出的 最小 弓箭数 。
示例 1:
输入:points = [[10,16],[2,8],[1,6],[7,12]] 输出:2 解释:气球可以用2支箭来爆破: -在x = 6处射出箭,击破气球[2,8]和[1,6]。 -在x = 11处发射箭,击破气球[10,16]和[7,12]。
示例 2:
输入:points = [[1,2],[3,4],[5,6],[7,8]] 输出:4 解释:每个气球需要射出一支箭,总共需要4支箭。
示例 3:
输入:points = [[1,2],[2,3],[3,4],[4,5]] 输出:2 解释:气球可以用2支箭来爆破: - 在x = 2处发射箭,击破气球[1,2]和[2,3]。 - 在x = 4处射出箭,击破气球[3,4]和[4,5]。
提示:
1 <= points.length <= 105
points[i].length == 2
-231 <= xstart < xend <= 231 - 1