给定一个区间的集合 intervals ,其中 intervals[i] = [starti, endi] 。返回 需要移除区间的最小数量,使剩余区间互不重叠 。
注意 只在一点上接触的区间是 不重叠的。例如 [1, 2] 和 [2, 3] 是不重叠的。
题解
法一 贪心法+右边界排序
改为计算最多可以选多少个互不重叠的区间,那么没选的区间就是要移除的最小的区间。
把 intervals 按照右端点从小到大排序。
初始化计数器 ans=0,上一个选的区间的右端点 preR=−∞。
遍历 intervals,如果发现 intervals[i][0]≥preR,那么选 intervals[i],把 ans 加一,更新 preR=intervals[i][1]。
遍历结束后,ans 就是不重叠区间个数的最大值,那么需要移除的区间个数的最小值就是 n−ans。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
//右边界排序
Arrays.sort(intervals,(i1,i2)->(i1[1]-i2[1]));
//记录最大不重叠区间的数量
int ans=0;
//上一个区间的右边界
int pre=Integer.MIN_VALUE;
for(int[] tmp:intervals){
if(tmp[0]>=pre){
ans++;
pre=tmp[1];
}
}
return intervals.length-ans;
}
}
算法
把 intervals 按照右端点从小到大排序。
初始化计数器 ans=0,上一个选的区间的右端点 preR=−∞。
遍历 intervals,如果发现 intervals[i][0]≥preR,那么选 intervals[i],把 ans 加一,更新 preR=intervals[i][1]。
遍历结束后,ans 就是不重叠区间个数的最大值,那么需要移除的区间个数的最小值就是 n−ans。
法二 动态规划法
改为计算最多可以选多少个互不重叠的区间,那么没选的区间就是要移除的最小的区间。
将所有的 n 个区间按照右端点从小到大进行排序,随后使用动态规划的方法求出区间数量的最大值。
dp[i]代表以区间i为最后一个区间,能包含的互不重叠的区间数的最大值
1.先把数组按右边界排序
2.如果inter[j][0]>=inter[i][1],inter[j]可以接在inter[i]的右侧,dp[i]=Math.max(dp[i],dp[j]+1)
注:为什么要排序?为什么要按照右端点排序?
选择右端点最小的区间 A 后,左端点小于 A 的右端点的区间都与 A 相交,都不能选。
因此,为了方便计算下一个可以选的区间,按照右端点从小到大排序。
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
int[] dp = new int[intervals.length];
Arrays.fill(dp, 1);
int max=1;
if (intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, (a,b)-> (a[1]-b[1]));
for(int i=0;i<intervals.length;i++){
for(int j=i;j<intervals.length;j++){
if(intervals[j][0]>=intervals[i][1]){
dp[j]=Math.max(dp[j],dp[i]+1);
max=Math.max(dp[j],max);
}
}
}
return intervals.length-max;
}
}