56. 合并区间
Origin: LeetCode 56
题目描述
给定一个区间集合 intervals,其中 intervals[i] = [start, end],合并所有重叠的区间,返回不重叠的区间数组。
示例
Input: intervals = [[1, 3], [2, 6], [8, 10], [15, 18]]
Output: [[1, 6], [8, 10], [15, 18]]
Explanation: [1, 3] 和 [2, 6] 重叠,合并为 [1, 6]
Input: intervals = [[1, 4], [4, 5]]
Output: [[1, 5]]
Explanation: [1, 4] 和 [4, 5] 重叠(端点接触算重叠)
约束
- 1 <= intervals.length <= 10
- intervals[i].length == 2
- 0 <= start <= end <= 10
关键信息
- 先按 start 排序
- 遍历,当前区间和结果最后一个区间比较
- 重叠 → 合并(取较大的 end)
- 不重叠 → push 到结果
Resolution
我的解法
function merge(intervals: number[][]): number[][] {
if (!intervals.length) return []
intervals.sort((a, b) => a[0] - b[0])
let result: number[][] = []
for (let i = 0; i < intervals.length; i++) {
let [start, end] = intervals[i]
let right = i + 1
let tmpRes: number[] = [start, end]
while (intervals[right] && end >= intervals[right][0] && right < intervals.length) {
end = Math.max(intervals[right][1], end)
tmpRes = [start, end]
i = right
right++
}
result.push(tmpRes)
}
return result
}标准解法(更简洁)
function merge(intervals: number[][]): number[][] {
if (!intervals.length) return []
intervals.sort((a, b) => a[0] - b[0])
const result: number[][] = [intervals[0]]
for (let i = 1; i < intervals.length; i++) {
const last = result[result.length - 1]
if (intervals[i][0] <= last[1]) {
// 重叠,合并 end
last[1] = Math.max(last[1], intervals[i][1])
} else {
// 不重叠,push
result.push(intervals[i])
}
}
return result
}解题思路
排序后遍历,和结果最后一个区间比较:
- 当前区间 start <= last 的 end → 重叠,合并(取较大的 end)
- 否则 → 不重叠,push 到结果
你的解法 vs 标准解法
你的写法用 while 内层循环批量合并 + i = right 跳过已合并的区间。标准解法只用 for + if,每次只和结果最后一个比。两种都正确,标准解法更简洁,不需要手动控制 i。
复杂度
- 时间:O(n log n),排序
- 空间:O(n),结果数组