506,无重叠区间_编程开发

You deserve someone who loves you with every beat of his heart.

你值得拥有一个全心全意爱你的人。

问题描述

给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。

注意:

  1. 可以认为区间的终点总是大于它的起点。
  2. 区间 [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]区间

506,无重叠区间_无重叠区间_02

代码如下

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”即可获取下载链接。


如果觉得有用就点个"赞"吧