Given a list of intervals
, remove all intervals that are covered by another interval in the list.
Interval [a,b)
is covered by interval [c,d)
if and only if c <= a
and b <= d
.
After doing so, return the number of remaining intervals.
Example 1:
Input: intervals = [[1,4],[3,6],[2,8]] Output: 2 Explanation: Interval [3,6] is covered by [2,8], therefore it is removed.
Example 2:
Input: intervals = [[1,4],[2,3]] Output: 1
Example 3:
Input: intervals = [[0,10],[5,12]] Output: 2
Example 4:
Input: intervals = [[3,10],[4,10],[5,11]] Output: 2
Example 5:
Input: intervals = [[1,2],[1,4],[3,4]] Output: 1
Constraints:
1 <= intervals.length <= 1000
intervals[i].length == 2
0 <= intervals[i][0] < intervals[i][1] <= 10^5
- All the intervals are unique.
删除被覆盖区间。
题意是给一些 intervals,以arrays of arrays表示,给你一个区间列表,请你删除列表中被其他区间所覆盖的区间。只有当 c <= a 且 b <= d 时,我们才认为区间 [a,b) 被区间 [c,d) 覆盖。在完成所有删除操作后,请你返回列表中剩余区间的数目。
这里我给出一个图示,帮助理解。题意要求只有类似这样的 [c, d) 才能完全覆盖 [a, b),从而我们可以只保留 [c, d)。
/*[c, d)[a, b)[1, 10)[1, 5)[1, 3)*/
这道题依然是扫描线类型的题目,那么思路无非是对 start 排序或者是对 end 排序。这道题需要对 start 和 end 都要排序。先对 start 按升序排序,目的是把 start 较小的 interval 放在前面,那么 start 在后的 interval 会比较好比较,方便删除;对 start 相同的 interval,我们按降序对 end 排序,这样end较大的在前 - 区间跨度大的在前。这里的逻辑是当 start 相同的时候,end 大的在前,先被遍历到,所以 end 小的也会很方便地被判断出来是否需要去掉。
这道题我提供两种做法,本质都是扫描线,区别在于 count 变量的定义。第一种方法这里代码中的 count 变量记录的是可以被保留下来的 interval 的数量。对于第一个 interval,因为他的 end 是跟 0 比较,所以第一个 interval 可以被保留。对于之后的每一个 interval,如果他的 end 大于之前的 prevEnd,则说明这是一个需要被保留的interval。可以参考我给出的图示,如果先出现的是 [a, b),后出现的是 [c, d),那么 [c, d) 就可以被保留。事实上经过排序,也应该是先遍历到 [a, b)。
时间O(nlogn)
空间O(1)
Java实现
1 class Solution { 2 public int removeCoveredIntervals(int[][] intervals) { 3 // start较小的在前 4 // end较大的在前 5 Arrays.sort(intervals, (a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]); 6 int count = 0; 7 int end = 0; 8 int prevEnd = 0; 9 for (int[] cur : intervals) { 10 end = cur[1]; 11 if (prevEnd < end) { 12 count++; 13 prevEnd = end; 14 } 15 } 16 return count; 17 } 18 }
第二种方法代码中代码中的 count 变量记录的是需要被去掉的 interval 的数量。时间空间复杂度相同。注意第 12 行,如果当前区间的end <= prevEnd,这就相当于是例子中的 b 遇到了 d,[a, b) 就需要被去掉。
Java实现
1 class Solution { 2 public int removeCoveredIntervals(int[][] intervals) { 3 // start较小的在前 4 // end较大的在前 5 Arrays.sort(intervals, (a, b) -> a[0] == b[0] ? b[1] - a[1] : a[0] - b[0]); 6 int count = 0; 7 int prevEnd = 0; 8 int end = 0; 9 int len = intervals.length; 10 for (int[] cur : intervals) { 11 end = cur[1]; 12 if (end <= prevEnd) { 13 count++; 14 continue; 15 } 16 prevEnd = end; 17 } 18 return len - count; 19 } 20 }