相关企业
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。 示例 1:
css
输入: intervals = [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
lua
输入: intervals = [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
提示:
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104
解法
核心思路:排序 + 合并
-
排序预处理 :将所有区间按起始位置升序排序
-
合并重叠区间:
- 遍历排序后的区间列表
- 维护当前合并区间
[start, end]
- 若当前区间起始位置 ≤ 上一区间的结束位置(存在重叠),则更新合并区间的结束位置
- 若没有重叠,则将前一合并区间加入结果,并开始新合并区间
ini
import java.util.*;
class Solution {
public int[][] merge(int[][] intervals) {
// 1. 排序:按区间起始位置升序
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
List<int[]> merged = new ArrayList<>();
int start = intervals[0][0];
int end = intervals[0][1];
// 2. 遍历合并
for (int i = 1; i < intervals.length; i++) {
if (intervals[i][0] <= end) { // 有重叠
end = Math.max(end, intervals[i][1]); // 扩展结束位置
} else { // 无重叠
merged.add(new int[]{start, end}); // 保存当前合并区间
start = intervals[i][0]; // 新合并区间开始
end = intervals[i][1];
}
}
merged.add(new int[]{start, end}); // 添加最后一个合并区间
// 3. 转为数组输出
return merged.toArray(new int[merged.size()][]);
}
}
算法步骤解析(以示例1 [[1,3],[2,6],[8,10],[15,18]]
为例)
- 排序后:保持顺序不变 [1,3] -> [2,6] -> [8,10] -> [15,18]
- 初始化 :
start=1, end=3
- 遍历 :
- 第1区间
[2,6]
:2 ≤ 3
→ 有重叠end = max(3,6) = 6
- 状态:
[1,6]
- 第2区间
[8,10]
:8 > 6
→ 无重叠- 保存
[1,6]
- 新区间:
start=8, end=10
- 保存
- 第3区间
[15,18]
:15 > 10
→ 无重叠- 保存
[8,10]
- 新区间:
start=15, end=18
- 保存
- 第1区间
- 结束 :保存最后一个区间
[15,18]
- 输出 :
[[1,6],[8,10],[15,18]]

关键优势
- 排序保证连续性:排序后只需比较相邻区间
- 合并逻辑简单:只需维护当前合并区间的结束位置
- 原地操作:无需额外数据结构(仅使用链表存储结果)