[前端]_一起刷leetcode 1288. 删除被覆盖区间

168 阅读3分钟

这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战

题目

1288. 删除被覆盖区间

给你一个区间列表,请你删除列表中被其他区间所覆盖的区间。

只有当 c <= a 且 b <= d 时,我们才认为区间 [a,b) 被区间 [c,d) 覆盖。

在完成所有删除操作后,请你返回列表中剩余区间的数目。

 

示例:

输入: intervals = [[1,4],[3,6],[2,8]]
输出: 2
解释: 区间 [3,6] 被区间 [2,8] 覆盖,所以它被删除了。

 

提示: ​​​​​​

  • 1 <= intervals.length <= 1000
  • 0 <= intervals[i][0] < intervals[i][1] <= 10^5
  • 对于所有的 i != jintervals[i] != intervals[j]

思路

  1. 对所有区间进行排序,按照左边界的先后位置进行排序,这样子后面的元素就不用比较左边界了,直接比较右边界即可;
  2. 遍历数组,判断当前的右边界在之前出现的区间中有没有被覆盖过,如果有的话说明这个区间整个是无效区间,因为前面的元素左边界肯定覆盖当前元素的左边界了,如果右边界也覆盖说明当前区间是个子区间,这时候区间数量减一,表示删除了当前区间;
  3. 遍历结束后,返回当前的区间的剩余数量即可。

实现

/**
 * @param {number[][]} intervals
 * @return {number}
 */
var removeCoveredIntervals = function(intervals) {
    // 按左边界进行排序,同时右边界越大越好
    intervals.sort((a, b) => {
        if (a[0] === b[0]) {
            return b[1] - a[1];
        }

        return a[0] - b[0];
    });

    // 记录所有的区间数量,如果有无效区间则数量 - 1;
    let result = intervals.length;
    
    // 遍历每个区间判断是否有效
    for (let i = 1; i < intervals.length; i++) {
        // 由于左边界已经排序过了,我们比较右边界有没有被覆盖过即可
        for (let j = 0; j < i; j++) {
            if (intervals[j][1] >= intervals[i][1]) {
                result--;
                break;
            }
        }
    }

    return result;
};

贪心优化

  1. 实际上我们排序完,前面元素的左边界肯定是覆盖了当前元素的左边界了,我们没必要跑双重循环去比较之前有没有大于这个元素的右边界,只需要在每一轮跑完的时候记录一下我们所拥有的最大右边界即可;
  2. 然后我们遍历的时候,只需要判断上一轮的右边界是否比当前的右边界小即可,如果是的话,重新定义最大的右边界,同时当前的有效区间数量+1;
  3. 如果当前的右边界小于等于之前记录的,说明之前的区间已经囊括了当前区间,那么不用做任何操作;
  4. 最终一轮遍历结束后返回我们记录的有效区间数量即可。

实现

/**
 * @param {number[][]} intervals
 * @return {number}
 */
var removeCoveredIntervals = function(intervals) {
    // 按左边界进行排序,同时右边界越大越好
    intervals.sort((a, b) => a[0] - b[0] || b[1] - a[1]);

    // 记录有效的数量
    let result = 0;
    // 记录所走过的最大的右边界
    let right = 0;
    for (let i = 0; i < intervals.length; i++) {
        // 排序后,左边界已经肯定是依次递增了,判断右边界的位置即可
        if (right < intervals[i][1]) {
            result++;
            right = intervals[i][1];
        }
    }

    return result;
};

最终结果

image.png

看懂了的小伙伴可以点个关注、咱们下道题目见。如无意外以后文章都会以这种形式,有好的建议欢迎评论区留言。