You deserve someone who loves you with every beat of his heart.
你值得拥有一个全心全意爱你的人。
问题描述
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
注意:
- 可以认为区间的终点总是大于它的起点。
- 区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
示例 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,如果后面区间的头小于当前区间的尾,
比如当前区间是[3,6],后面区间是[4,5]或者是[5,9]
说明这两个区间有重叠,必须要移除一个,那么要移除哪个呢,为了防止在下一个区间和现有区间有重叠,我们应该让现有区间越短越好,所以应该移除尾部比较大的,保留尾部比较小的。
2,如果后面区间的头不小于当前区间的尾,说明他们没有重叠,不需要移除
如下图区间[1,2]和[1,3]有了重叠,我们要移除尾部比较大的,也就是红色的[1,3]区间
代码如下
1public int eraseOverlapIntervals(int[][] intervals) { 2 if (intervals.length == 0) 3 return 0; 4 //先排序 5 Arrays.sort(intervals, (a, b) -> a[0] - b[0]); 6 //记录区间尾部的位置 7 int end = intervals[0][1]; 8 //需要移除的数量 9 int count = 0;10 for (int i = 1; i < intervals.length; i++) {11 if (intervals[i][0] < end) {12 //如果重叠了,必须要移除一个,所以count要加1,13 //然后更新尾部的位置,我们取尾部比较小的14 end = Math.min(end, intervals[i][1]);15 count++;16 } else {17 //如果没有重叠,就不需要移除,只需要更新尾部的位置即可18 end = intervals[i][1];19 }20 }21 return count;22}
总结
这题关键点在于排序之后要怎么确定两个区间是否相交,确定之后就简单了,如果相交我们只需要移除尾部较大的即可。
截止到目前我已经写了500多道算法题了,为了方便大家阅读,我把部分算法题整理成了pdf文档,目前有800多页,大家可以在公众号中回复关键字“pdf”即可获取下载链接。
如果觉得有用就点个"赞"吧