[dp/贪心]435. 无重叠区间-----经典问题
无重叠区间是一类十分经典的问题,很多问题的模型就是基于这一就无重叠区间问题的。
首先,一个很直接的思路就是这类题目和LIS(最长上升子序列问题)很像。
所以考虑使用动态规划
来解这道题
import java.util.Arrays;
import java.util.Comparator;
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if(intervals.length == 0) return 0 ;
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] a, int[] b) {
if (a[1] < b[1])
return a[1] - b[1];
return a[0] - b[0];
}
});
int n = intervals.length;
int[] dp = new int[n];
dp[0] = 1;//基本问题的解,就是只选自己
for (int i = 1; i < n; i++) {
for (int j = 0; j < i; j++) {
if (intervals[i][0] >= intervals[j][1] && dp[i] < 1 + dp[j]) {
dp[i] = dp[j] + 1;
}
}
}
//和LIS问题一样一定是返回dp数组中的最大值,而不是dp[n-1]
int res = 0;
for (int i = 0; i < n; i++) {
res = Math.max(res,dp[i]);
}
return n - res;
}
public static void main(String[] args) {
int[][] ins = {{1, 2}, {2,3}};
System.out.println(new Solution().eraseOverlapIntervals(ins));
}
}
其实这类问题可以使用贪心算法来解决,证明的方法是使用反证法.
贪心策略:每次选择最快结束的区间,留给更多的空间给后续的区间
import java.util.Arrays;
class Solution {
public int eraseOverlapIntervals(int[][] intervals) {
if (intervals.length == 0) return 0;
Arrays.sort(intervals, (a, b) -> {
if (a[1] != b[1])
return a[1] - b[1];
return a[0] - b[0];
});
for (int i = 0; i < intervals.length; i++) {
for (int j = 0; j < intervals[0].length; j++) {
System.out.print(intervals[i][j]);
}
System.out.println();
}
int res = 1;
int end = intervals[0][1];//选择第一个区间的末端
//每次选择区间结尾最小的
for (int i = 0; i < intervals.length; i++) {
if(end <= intervals[i][0]){
res++;
end = intervals[i][1];
}
}
return intervals.length - res;
}
public static void main(String[] args) {
int[][] ins = {{1, 2}, {3, 5}, {2, 6}};
System.out.println(new Solution().eraseOverlapIntervals(ins));
}
}