版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/majichen95/article/details/89081697
给定一些区间,找到需要移除的最小区间数,以使其余的区间不重叠。
样例
样例1:
输入: [ [1,2], [2,3], [3,4], [1,3] ]
输出: 1
解释: [1,3] 被移除后,剩下的区间将不再重叠。
样例2:
输入: [ [1,2], [1,2], [1,2] ]
输出: 2
解释: 需要将两个 [1,2] 移除使得剩下的区间不重合。
样例3:
输入: [ [1,2], [2,3] ]
输出: 0
解释: 不需要移除任何区间因为本身就没有任何区间重合。
注意事项
- 可以假设区间的终止点一定比起始点大。
- 区间[1,2]和[2,3]虽然边缘重合,但是它们并未重叠。
解题思路1:
转换题意为找到最长不重叠区间的数目,最后结果只需要list.size()-最长不重叠区间数目。
而找最长不重叠子序列,就类似Lintcode 76. 最长上升子序列,将区间按start升序,end升序,依次查找即可。
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param intervals: a collection of intervals
* @return: the minimum number of intervals you need to remove
*/
public int eraseOverlapIntervals(List<Interval> intervals) {
// write your code here
//按照start升序,end升序
Collections.sort(intervals, new Comparator<Interval>(){
@Override
public int compare(Interval a, Interval b){
if(a.start != b.start)
return a.start - b.start;
else
return a.end - b.end;
}
});
int len = intervals.size();
int[] dp = new int[len];
int res = 0;
for(int i=0; i<len; i++){
dp[i] = 1;
for(int j=0; j<i; j++)
if(intervals.get(j).end <= intervals.get(i).start)
dp[i] = Math.max(dp[i], 1 + dp[j]);
res = Math.max(res, dp[i]);
}
return len - res;
}
}
解题思路2:
贪心算法。注意每次选择中,结尾很重要,结尾越小,留给后面的空间就越大。所以可以按照end升序排序,每次选择结尾最早,且和前一个区间不重叠的区间。
/**
* Definition of Interval:
* public classs Interval {
* int start, end;
* Interval(int start, int end) {
* this.start = start;
* this.end = end;
* }
* }
*/
public class Solution {
/**
* @param intervals: a collection of intervals
* @return: the minimum number of intervals you need to remove
*/
public int eraseOverlapIntervals(List<Interval> intervals) {
// write your code here
//按照end升序
Collections.sort(intervals, new Comparator<Interval>(){
@Override
public int compare(Interval a, Interval b){
if(a.end != b.end)
return a.end - b.end;
else
return a.start - b.start;
}
});
int res = 1; //记录最长不重叠区间数目
int pre = 0; //记录i之前的不重叠区间位置
for(int i=1; i<intervals.size(); i++){
if(intervals.get(i).start >= intervals.get(pre).end){
res++;
pre = i;
}
}
return intervals.size() - res;
}
}