问题描述
- 给定一组区间,问最少删除多少个区间,才能让剩下的区间不重合
- 地址
问题描述
- 问最少删除多少个区间,等价于最多保留多少个区间。
- 该题有两种解法:
- 动态规划:
该解法类似于 LeetCode 300. Longest Increasing Subsequence(最长递增子序列) 。为了判别是否重叠,我们先对区间数组进行排序(按照区间的左边界进行排序),然后我们可以求解以每一个区间作为结尾的最长上升的长度,然后全局最长便是最多可以保留多少个空间。
时间复杂度:O(n^2) - 贪心算法:
贪心很大几率是搭配排序使用的,对区间数组按照区间的右边界进行排序,这样我们每次选的都是右边界最小(这样可以保证右侧剩下更多的空间存放更多的区间,这便是贪心)并且不与前一个区间重叠的。
时间复杂度:O(nlogn)
- 动态规划:
最终,最少删除数量便是区间数组的长度减去最大递增数量。
经验教训
- 贪心到底怎么贪
代码实现
- 动态规划
public int eraseOverlapIntervals(Interval[] intervals) {
if (intervals == null || intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, new Comparator<Interval>(){
public int compare(Interval o1, Interval o2) {
if (o1.start != o2.start) {
return o1.start - o2.start;
}
return o1.end - o2.end;
}
});
int[] dp = new int[intervals.length];
Arrays.fill(dp, 1);
int maxIncrease = 1;
for (int i = 1; i < dp.length; ++i) {
for (int j = 0; j < i; ++j) {
if (intervals[i].start >= intervals[j].end) {
dp[i] = Math.max(dp[j] + 1, dp[i]);
}
}
maxIncrease = Math.max(maxIncrease, dp[i]);
}
return intervals.length - maxIncrease;
}
- 贪心
public int eraseOverlapIntervals(Interval[] intervals) {
if (intervals == null || intervals.length == 0) {
return 0;
}
Arrays.sort(intervals, new Comparator<Interval>(){
public int compare(Interval o1, Interval o2) {
//if (o1.end != o2.end) {
return o1.end - o2.end;
// }
// return o1.start - o2.start;
}
});
int maxLen = 1;
int preEnd = intervals[0].end;
for (int i = 1; i < intervals.length; ++i) {
if (intervals[i].start >= preEnd) {
++maxLen;
preEnd =intervals[i].end;
}
}
return intervals.length - maxLen;
}