631 字
3 分钟
合并区间

题目描述#

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

解题思路#

  1. 区间排序
    • 按区间起始点升序排序
    • 确保重叠区间相邻
  2. 顺序合并
    • 初始化结果数组,添加首个区间
    • 遍历后续区间,判断是否与末位区间重叠
  3. 重叠判定
    • 当前区间起始 ≤ 末位区间结束 → 重叠
    • 更新末位区间结束为两者最大值
  4. 非重叠处理
    • 直接将新区间加入结果
  5. 边界处理
    • 空输入直接返回
    • 单区间无需合并

关键洞察#

  1. 排序必要性
    • 无序区间无法保证相邻扫描覆盖所有重叠
    • 起始点排序使重叠区间连续分布
  2. 贪心策略
    • 每次只关注与最近结果区间的重叠
    • 避免复杂回溯机制
  3. 端点处理
    • 区间[1,3]和[3,5]视为重叠
    • 需合并为[1,5]
  4. 空间优化
    • 原地修改结果数组
    • 避免额外存储

复杂度分析#

指标说明
时间复杂度O(n log n):排序主导,合并扫描O(n)
空间复杂度O(1) 或 O(n):排序栈空间O(log n),结果O(n)

代码实现#

/**
* @param {number[][]} intervals
* @return {number[][]}
*/
var merge = function (intervals) {
intervals = intervals.sort((a, b) => a[0] - b[0]);
const merged = [];
for (let i = 0; i < intervals.length; i++) {
const [l, r] = intervals[i];
if (merged.length === 0 || merged[merged.length - 1][1] < l) {
merged.push([l, r])
} else {
merged[merged.length - 1][1] = Math.max(
merged[merged.length - 1][1],
r
)
}
}
return merged;
};

实际应用场景#

  1. 日程管理:合并重叠会议时间: [9,10],[9:30,11]] → [[9,11]]`
  2. 基因序列比对:合并DNA片段重叠区域`
  3. 带宽分配:优化IP地址区间分配`
  4. 交通调度:合并车辆路线重叠时段`

相似题目#

合并区间
https://website-truelovings-projects.vercel.app/posts/algorithms/合并区间/
作者
欢迎来到StarSky的网站!
发布于
2025-08-18
许可协议
CC BY-NC-SA 4.0