[路飞]_LeetCode_56. 合并区间

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

题目

以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。

示例 1:

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
复制代码

示例 2:

输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
复制代码

  提示:

1 <= intervals.length <= 10的4次方
intervals[i].length == 2
0 <= starti <= endi <= 10的4次方
复制代码

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/me… 著作权归领扣网络所有。

解题思路

  1. 将区间转换成括号:左区间转换成做括号 [l, 1],右区间转换成右括号 [r, -1]
  2. 然后将转换结果进行排序,先按数字排升序,数字相同的按括号排降序。
  3. 最后遍历排序后的结果,累计括号的和,当和为0时说明左右括号匹配上了,上一个数字和当前数字为一个合并好的区间。

示例1 [[1,3],[2,6],[8,10],[15,18]] 的处理过程如下图,[1,3] 和 [2,6] 合并后为一个区间。

image.png

代码实现

var merge = function(intervals) {
    const arr = []

    //把区间转换成括号,1代表左括号,-1代表右括号
    for (const [l, r] of intervals) {
        arr.push([l, 1])
        arr.push([r, -1])
    }

    //排序:先按区间数字排升序,如果数组一样则再按括号排倒序
    arr.sort((a, b) => a[0] === b[0] ? b[1] - a[1] : a[0] - b[0])

    const ans = []
    let l = -1  //记录区间左侧数字
    let sum = 0 //累计括号的和

    for (const [a, b] of arr) {
        //如果需要,将a设置为区间左侧的数字
        if (l === -1) l = a

        //累计括号的值
        sum += b

        //和为0时说明遇到了右括号,则[l, a]为一个有效的合并后的区间
        if (sum === 0) {
            ans.push([l, a])
            //将左括号重置为-1
            l = -1
        }
    }

    return ans
};
复制代码

如有错误欢迎指出,欢迎一起讨论!

Guess you like

Origin juejin.im/post/7068094544641785863
Recommended