zoukankan      html  css  js  c++  java
  • [LeetCode] 1288. Remove Covered Intervals

    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 }

    扫描线相关题目

    LeetCode 题目总结

  • 相关阅读:
    SQL Server数据库损坏、检测以及简单的修复办法
    迭代法
    求两个数组的交集
    jQuery的动画处理总结
    ASP.NET MVC企业开发的基本环境
    ASP.NET WebForm 的路由
    CMStepCounter Class Refernce
    C++输入一个字符串,把其中的字符按照逆序输出的两种方法
    5.2 列出表的列
    Mac Outlook数据文件的位置
  • 原文地址:https://www.cnblogs.com/cnoodle/p/13769066.html
Copyright © 2011-2022 走看看