题目描述
题目分析
- 计算让一组区间不重叠所需要移除的区间个数的最小值
- 反之就是计算最多能组成的不重叠区间个数的最大值,然后用总区间个数减去即可
解法分析
- 这道题是一个很经典的贪心算法问题
Interval Scheduling
(区间调度问题) - 如果把一个区间表示这个时间段内要完成一个任务,那就类似于在一段时间内找到最大的完成任务数
- 显然一个时间段内,一个人无法完成两件事,所以完成一个任务所用的时间越短,完成的任务越多
- 那是每次选择完成用时最短的,还是开始最早的,还是其他的更优的呢?
- 因为区间是固定的,所以我们每次都可以选择一个最早结束的,然后移除与之冲突的,这样就能尽量多的完成任务
选择的区间结尾越小,留给后面的区间的空间越大,那么后面能够选择的区间个数也就越大
- 所以要先对数组排序,按照区间结尾值进行排序
- 众所周知,能用贪心算法完成的题目,自然也可以使用动态规划法完成,因为贪心算法是动态规划中的一种比较特殊的方法,具体可看《官方题解》
代码
- 贪心法
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length == 0) return 0;
// 对数组进行排序,按照结尾数值升序排序
// 用lambda表达式也可,不过会导致算法时间较长
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
return o1[1] - o2[1];
}
});
// 初始区间个数
int cnt = 1;
// 初始区间结尾
int end = intervals[0][1];
for(int i = 1; i<intervals.length; i++){
// 如果该区间的起点小于结尾,表示有重叠,删去
if(intervals[i][0] < end){
continue;
}
// 区间不重叠就并入
end = intervals[i][1];
cnt++;
}
return intervals.length - cnt;
}
}