力扣热题100:合并区间详解(Java实现)(56)
题目描述
解题思路
核心思想:排序 + 贪心合并
排序预处理 先按区间左端点升序排序,使重叠的区间相邻。这是合并操作的基础,确保只需一次遍历即可完成合并。
- 排序后,重叠区间必然连续分布(如
[1,3]
和[2,6]
相邻)。
- 排序后,重叠区间必然连续分布(如
贪心合并 遍历排序后的区间列表,动态维护当前合并区间的右边界:
- 若当前区间左端点 ≤ 上一区间的右端点 → 合并(更新右边界为两者最大值);
- 否则 → 将上一区间加入结果,开启新区间
- 贪心策略:每次合并时取最大右边界,确保覆盖最广 。
代码详解(逐行分析)
class Solution {public int[][] merge(int[][] intervals) {// Step 1: 按左端点升序排序Arrays.sort(intervals, new Comparator<int[]>() {public int compare(int[] o1, int[] o2) {return o1[0] - o2[0]; // 比较左端点}});// Step 2: 动态合并重叠区间List<int[]> result = new ArrayList<>();for (int i = 0; i < intervals.length; i++) {int left = intervals[i][0];int right = intervals[i][1];// 情况1:结果集为空 或 当前区间与上一区间不重叠 → 直接添加if (result.size() == 0 || result.get(result.size() - 1)[1] < left) {result.add(new int[]{left, right});} // 情况2:当前区间与上一区间重叠 → 合并(更新右边界)else {result.get(result.size()-1)[1]=Math.max(right, result.get(result.size()-1)[1]);}}// Step 3: 转换List为二维数组return result.toArray(new int[result.size()][]);}
}
关键逻辑解析
- 排序函数
Arrays.sort
中使用自定义比较器,确保按区间左端点(o1
)升序排列 。 - 合并条件
result.size() == 0
:结果集为空时,直接添加第一个区间;last [1](@ref) < left
:当前区间左端点大于上一区间的右端点 → 无重叠;- 否则更新上一区间的右边界为
max(last [1](@ref), right)
。
- 结果转换
result.toArray()
将ArrayList
转为二维数组,满足返回值类型要求。
复杂度分析
- 时间复杂度:O(nlogn)O(nlogn) 排序占主导(O(nlogn)O(nlogn)),遍历仅需 O(n)O(n) 。
- 空间复杂度:O(n)O(n) 存储结果需额外空间(最坏情况下无重叠,需存所有区间) 。
总结与拓展
- 为什么贪心策略有效? 排序后,局部最优(每次合并取最大右边界)可推导出全局最优解 。
- 边界处理技巧
- 输入空数组时,
result.size()==0
确保安全 ; - 区间端点相等(如
[1,4]
和[4,5]
)视为重叠 。
- 输入空数组时,