区间类题目是算法面试和刷题中绕不开的一大类,而 「插入区间」 是其中非常经典、非常有代表性的一道题。
这道题不考花里胡哨的技巧,核心在于:
你能不能把“区间合并”的过程在脑子里跑一遍。
本文会结合完整代码,从「题目理解 → 思路拆解 → 代码分析 → 易错点总结」一步一步讲清楚。
一、题目描述
给你一组 已经按起点升序排列、且 互不重叠 的区间 intervals,
再给你一个新区间 newInterval。
要求:
把 newInterval 插入到原来的区间中,并保证最终结果仍然有序、且区间不重叠。
示例:
intervals = [[1,3],[6,9]]
newInterval = [2,5]
结果:
[[1,5],[6,9]]
二、这道题到底在考什么?
这道题本质只做三件事:
- 把 newInterval 前面完全不冲突的区间 直接放进结果
- 把 newInterval 和可能重叠的区间合并
- 把 后面剩余的区间继续合并或直接放入
重点不在代码,而在于你是否能分清楚这三段区间。
三、整体思路拆解
我们按区间与 newInterval 的关系来划分:
第一部分:完全在 newInterval 左边的区间
条件:
interval.end < newInterval.start
这些区间 一定不会和 newInterval 产生任何重叠,可以直接加入结果。
第二部分:处理 newInterval 本身
有两种情况:
- 前面没有区间
- 前一个区间和 newInterval 有重叠
判断方式:
result 为空
或者
result 最后一个区间的 end < newInterval.start
如果是第 1 种情况:
直接把 newInterval 放进去
如果是第 2 种情况:
说明有重叠,需要合并:
end = max(原 end, newInterval.end)
第三部分:处理 newInterval 后面的区间
对于剩下的每一个区间:
- 如果和结果最后一个区间不重叠 → 直接加入
- 如果有重叠 → 合并
四、代码实现(逐行讲解)
完整代码如下:
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int index = 0;
LinkedList<int[]> result = new LinkedList<>();
// 1. 先加入所有在 newInterval 左边的区间
for (int[] interval : intervals) {
if (interval[0] < newInterval[0]) {
result.add(interval);
index++;
} else {
break;
}
}
// 2. 处理 newInterval
if (result.size() == 0 || result.getLast()[1] < newInterval[0]) {
result.add(newInterval);
} else {
result.getLast()[1] = Math.max(result.getLast()[1], newInterval[1]);
}
// 3. 处理剩余区间
for (int i = index; i < intervals.length; i++) {
if (result.getLast()[1] < intervals[i][0]) {
result.add(intervals[i]);
} else {
result.getLast()[1] = Math.max(result.getLast()[1], intervals[i][1]);
}
}
return result.toArray(new int[result.size()][]);
}
}
五、为什么用 LinkedList?
这里使用 LinkedList<int[]> 的原因很简单:
- 需要频繁访问 最后一个区间
getLast()和add()都是 O(1)- 写起来语义清晰
当然,用 ArrayList 也可以,只是代码会稍微啰嗦一点。
六、手动走一遍示例,加深理解
示例:
intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]]
newInterval = [4,8]
执行流程:
- 加入
[1,2] - 加入
[3,5] [3,5]和[4,8]重叠 → 合并为[3,8][6,7]重叠 → 合并为[3,8][8,10]重叠 → 合并为[3,10][12,16]不重叠 → 直接加入
最终结果:
[[1,2],[3,10],[12,16]]
七、这道题最容易犯的错误
- 忘了区间是已经排序好的
- 边界判断写成
<=或<出错 - 合并时只更新
end,却错误地动了start - 直接在原数组上改,逻辑变得混乱
八、区间类题目的通用模板
这道题可以总结出一个通用套路:
- 排序(本题已给)
- 顺序遍历
- 看是否和「结果中的最后一个区间」重叠
- 不重叠就加,重叠就合并
后续你会发现:
- 合并区间
- 插入区间
- 区间交集
本质都是这个模板的变形。