题目:给定一个区间的集合 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 <= 10^5
intervals[i].length == 2
-5 * 10^4 <= starti < endi <= 5 * 10^4
方法一:动态规划(超出时间限制)
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
//对数组进行排序,将区间中0位置元素较小的排在前面,若0位置元素相等,则选择1位置元素较小的排在前面
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
if(o1[0] < o2[0] || (o1[0] == o2[0] && o1[1] < o2[1]))
return -1;
else if(o1[1] == o2[1] && o1[0] == o2[0])
return 0;
else
return 1;
}
});
int[] memo = new int[intervals.length];
Arrays.fill(memo, 1);
int max = 1;
for(int i = 1; i < intervals.length; i++) {
for(int j = 0; j < i; j++) {
if(intervals[i][0] >= intervals[j][1]) {
memo[i] = Math.max(memo[i], 1 + memo[j]);
}
}
max = Math.max(max, memo[i]);
}
return intervals.length - max;
}
}
方法二:贪心算法
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
//按照区间中索引为1的值较小的顺序排列
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] o1, int[] o2) {
if(o1[1] < o2[1] || (o1[1] == o2[1] && o1[0] < o2[0]))
return -1;
else if(o1[1] == o2[1] && o1[0] == o2[0])
return 0;
else
return 1;
}
});
int res = 1;
int pre = 0;
for(int i = 1; i < intervals.length; i++) {
if(intervals[i][0] >= intervals[pre][1]) {
res++;
pre = i;
}
}
return intervals.length - res;
}
}