跳到主要内容

56. 合并区间

题目描述

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

示例 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 <= 104
  • intervals[i].length == 2
  • 0 <= starti <= endi <= 104

出处LeetCode

解法一:排序

思路

我们可以先对区间集合 intervals 按照区间的左端点进行排序。接着,我们可以维护一个数组 merged,用来存储合并后的区间。我们可以遍历排序后的区间集合 intervals,对于每一个区间 interval,我们可以分为以下几种情况:

  • 如果 merged 为空,或者当前区间的左端点大于 merged 中最后一个区间的右端点,那么当前区间不与 merged 中的区间重合,我们可以直接将当前区间加入到 merged 中;
  • 如果当前区间的左端点小于 merged 中最后一个区间的右端点,那么当前区间与 merged 中的最后一个区间重合,我们可以合并这两个区间,即将 merged 中最后一个区间的右端点更新为这两个区间的右端点的最大值。
  • 最终,merged 中存储的就是合并后的区间。

代码

function merge(intervals: number[][]): number[][] {
if (intervals.length === 0) {
return [];
}

intervals.sort((a, b) => a[0] - b[0]);

const merged: number[][] = [intervals[0]];

for (let i = 1; i < intervals.length; i++) {
const interval = intervals[i];
const last = merged[merged.length - 1];
if (interval[0] > last[1]) {
merged.push(interval);
} else {
last[1] = Math.max(last[1], interval[1]);
}
}

return merged;
}

复杂度分析

  • 时间复杂度:O(nlogn)O(n \log n),其中 nn 为区间的数量。我们需要 O(nlogn)O(n \log n) 的时间来对区间集合 intervals 进行排序。
  • 空间复杂度:O(logn)O(\log n),其中 nn 为区间的数量。我们需要 O(logn)O(\log n) 的空间来存储排序后的区间集合。