LeetCode-56-合并区间
in LeetCode with 0 comment

LeetCode-56-合并区间

in LeetCode with 0 comment

原题地址:合并区间

给出一个区间的集合,请合并所有重叠的区间。

示例 1:

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

示例 2:

输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。

排序

两个被判定重叠的区间$[a_0,a_1]$和$[b_0,b_1]$,如果$a_0<b_0$,那么一定存在$a_1 \geq b_0$。所以我们只需要将原数组按每个区间的左端点进行排序,然后再依次判断相邻两个区间是否重叠并合并重叠的区间即可。

具体的实现代码如下:

/**
 * @param {number[][]} intervals
 * @return {number[][]}
 */
const merge1 = function(intervals) {
    // 根据左边界排序
    intervals.sort((a, b) => a[0] - b[0]);
    for (let i = 0; i < intervals.length - 1;) {
        let j = i + 1;
        // 依次合并符合条件的区间
        while (j < intervals.length && intervals[j][0] <= intervals[i][1]) {
            // 合并后区间的右端点为两者中较大的一个
            intervals[i][1] = Math.max(intervals[i][1], intervals[j][1]);
            intervals[j] = null; // 被合并的区间置为null
            j ++; // 判断下一个区间能不能被合并
        }
        // 跳过已经被合并的区间
        i = j;
    }
    // 过滤掉标记为null的区间
    return intervals.filter(item => item != null);
};

测试:

let start = new Date();
const test = merge1;
console.log(test([[1,3],[2,6],[8,10],[15,18]])); // [ [ 1, 6 ], [ 8, 10 ], [ 15, 18 ] ]
console.log(test([[1,4],[4,5]])); // [ [ 1, 5 ] ]
console.log(new Date().getTime() - start.getTime()); // 10

时间复杂度: 合并需要一次遍历,虽然代码中有两次循环,但是合并操作完成后会跳过被合并的部分,所以实际只进行了一轮遍历。时间复杂度为$O(N)$
空间复杂度: 原地操作,空间复杂度为$O(1)$