LeetCode Everyday - 删除被覆盖区间

97 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情 >>

删除被覆盖区间

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

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

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

示例1:

输入: 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 != j:intervals[i] != intervals[j]

解题思路:

1.  排序,按起点升序,若起点相同,按终点降序
2.  三种情况:覆盖区间、相交区间、不相交区间
3.  覆盖区间:删除该区间
4.  相交区间:合并,更新终点
5.  不相交区间:更新起点和终点

我的答案:

/**
 * @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]
    })
    // 分别取第一个元素的起点和终点, 设为初始起点和初始终点
    let left = intervals[0][0]
    let right = intervals[0][1]
    let res = 0
    // 遍历数组, 判断与起点的关系
    for (let i = 1; i < intervals.length; i++) {
        // 覆盖: 当前元素的起点大于初始起点, 且当前元素的终点小于初始终点, 将删除元素个数加一
        if (intervals[i][0] >= left && intervals[i][1] <= right) {
            res ++
        }
        // 相交: 当前元素的起点小于初始终点, 且当前元素终点初始终点, 将当前元素终点设为初始终点
        if (intervals[i][0] <= right && intervals[i][1] >= right) {
            right = intervals[i][1]
        }
        // 不相交: 当前元素起点大于初始终点, 将当前元素起点设为初始起点, 当前元素终点设为初始终点
        if (right < intervals[i][0]) {
            left = intervals[i][0]
            right = intervals[i][1]
        }
    }
    // 数组长度减去删除元素个数即为剩余区间数量
    return intervals.length - res
};

最后

如果有更好的解法或者思路, 欢迎在评论区和我交流~ ღ( ´・ᴗ・` )