435. 无重叠区间
描述
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
可以认为区间的终点总是大于它的起点。
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
链接
435. 无重叠区间 - 力扣(LeetCode) (leetcode-cn.com)
解法一:贪心
采用左边界排序,通过看下一个的左边界是或否大于上一个的右边界,来判断重复,并且取 最小的边界,统计的是取药去掉的重复的
解法二:贪心
按照右边界排序,就要从左向右遍历,因为右边界越小越好,只要右边界越小,留给下一个区间的空间就越大,所以从左向右遍历,优先选右边界小的。
总体思想是:按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数。
1 class Solution { 2 // 按照左边界进行排序 3 public int eraseOverlapIntervals1(int[][] intervals) { 4 if (intervals.length < 2) return 0; 5 Arrays.sort(intervals, (a,b) -> { 6 return Integer.compare(a[0], b[0]); 7 }); 8 // // 等同于 9 // Arrays.sort(intervals, new Comparator<int[]>(){ 10 // @Override 11 // public int compare(int[] o1, int[] o2) { 12 // if (o1[1] != o2[1]) { 13 // return Integer.compare(o1[1],o2[1]); 14 // } else { 15 // return Integer.compare(o1[0],o2[0]); 16 // } 17 // } 18 // }); 19 20 int remove = 0; 21 int pre = intervals[0][1]; 22 for (int i = 1; i < intervals.length; i++) { 23 if(pre > intervals[i][0]) { 24 remove++; 25 pre = Math.min(pre, intervals[i][1]); // 去除右边界大的那个 26 } else { 27 pre = intervals[i][1]; 28 } 29 } 30 return remove; 31 } 32 33 // 按照右边界进行排序,统计非交叉个数,再用总数减去 非交叉的,得到需要去除的区间个数 34 public int eraseOverlapIntervals(int[][] intervals) { 35 if (intervals.length < 2) return 0; 36 Arrays.sort(intervals, (a,b) -> { 37 return Integer.compare(a[1], b[1]); 38 }); 39 40 int res = 1; 41 for (int i = 1; i < intervals.length; i++) { 42 if(intervals[i -1][1] <= intervals[i][0]) { 43 res++; 44 } else { 45 intervals[i][1] = Math.min(intervals[i - 1][1], intervals[i][1]); 46 } 47 } 48 return intervals.length - res; 49 } 50 }
参考
carl