56. 合并区间(Merge Intervals)

频次 ★★★★ · 难度 🟡 · 高频:全厂

题目

区间集合,重叠的合并。

示例

输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]

思路

排序 + 贪心合并:按 start 排序,遍历时比较当前 start 与上一区间 end,重叠则合并(取最大 end),否则新增区间。

代码

public int[][] merge(int[][] intervals) {
    if (intervals.length == 0) return new int[0][];
    Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
    List<int[]> res = new ArrayList<>();
    int start = intervals[0][0], end = intervals[0][1];
    for (int i = 1; i < intervals.length; i++) {
        if (intervals[i][0] <= end) {            // 重叠
            end = Math.max(end, intervals[i][1]);
        } else {
            res.add(new int[]{start, end});
            start = intervals[i][0];
            end = intervals[i][1];
        }
    }
    res.add(new int[]{start, end});
    return res.toArray(new int[0][]);
}

复杂度

  • 时间:O(n log n) —— 排序
  • 空间:O(log n) —— 排序栈

边界条件

  • 空集合:返回空
  • 全重叠:合并为一个区间
  • 全不重叠:原样输出

变式

易错点

  • 排序用 a[0] - b[0](按 start),不是 end
  • 合并时 end 取两个区间的 max,不是直接取第二个的 end
  • 最后一个区间在循环外加入结果

面试追问

  • 如果区间达到百万级? 外部排序(外存归并)+ 流式合并

关联题