英文原文
You are given an array of non-overlapping intervals intervals
where intervals[i] = [starti, endi]
represent the start and the end of the ith
interval and intervals
is sorted in ascending order by starti
. You are also given an interval newInterval = [start, end]
that represents the start and end of another interval.
Insert newInterval
into intervals
such that intervals
is still sorted in ascending order by starti
and intervals
still does not have any overlapping intervals (merge overlapping intervals if necessary).
Return intervals
after the insertion.
Example 1:
Input: intervals = [[1,3],[6,9]], newInterval = [2,5] Output: [[1,5],[6,9]]
Example 2:
Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] Output: [[1,2],[3,10],[12,16]] Explanation: Because the new interval[4,8]
overlaps with[3,5],[6,7],[8,10]
.
Example 3:
Input: intervals = [], newInterval = [5,7] Output: [[5,7]]
Example 4:
Input: intervals = [[1,5]], newInterval = [2,3] Output: [[1,5]]
Example 5:
Input: intervals = [[1,5]], newInterval = [2,7] Output: [[1,7]]
Constraints:
0 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 105
intervals
is sorted bystarti
in ascending order.newInterval.length == 2
0 <= start <= end <= 105
中文题目
给你一个 无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
示例 1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5] 输出:[[1,5],[6,9]]
示例 2:
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] 输出:[[1,2],[3,10],[12,16]] 解释:这是因为新的区间[4,8]
与[3,5],[6,7],[8,10]
重叠。
示例 3:
输入:intervals = [], newInterval = [5,7] 输出:[[5,7]]
示例 4:
输入:intervals = [[1,5]], newInterval = [2,3] 输出:[[1,5]]
示例 5:
输入:intervals = [[1,5]], newInterval = [2,7] 输出:[[1,7]]
提示:
0 <= intervals.length <= 104
intervals[i].length == 2
0 <= intervals[i][0] <= intervals[i][1] <= 105
intervals
根据intervals[i][0]
按 升序 排列newInterval.length == 2
0 <= newInterval[0] <= newInterval[1] <= 105
通过代码
高赞题解
11.3 川普要赢了吗?
思路
用指针去扫 intervals
,最多可能有三个阶段:
- 不重叠的绿区间,在蓝区间的左边
- 有重叠的绿区间
- 不重叠的绿区间,在蓝区间的右边
逐个分析
不重叠,需满足:绿区间的右端,位于蓝区间的左端的左边,如
[1,2]
。- 则当前绿区间,推入 res 数组,指针 +1,考察下一个绿区间。
- 循环结束时,当前绿区间的屁股,就没落在蓝区间之前,有重叠了,如
[3,5]
。
现在看重叠的。我们反过来想,没重叠,就要满足:绿区间的左端,落在蓝区间的屁股的后面,反之就有重叠:绿区间的左端 <= 蓝区间的右端,极端的例子就是
[8,10]
。- 和蓝有重叠的区间,会合并成一个区间:左端取蓝绿左端的较小者,右端取蓝绿右端的较大者,不断更新给蓝区间。
- 循环结束时,将蓝区间(它是合并后的新区间)推入 res 数组。
剩下的,都在蓝区间右边,不重叠。不用额外判断,依次推入 res 数组。
代码
function insert(intervals, newInterval) {
const res = [];
let i = 0;
const len = intervals.length;
while (i < len && intervals[i][1] < newInterval[0]) { // 当前遍历的是蓝左边的,不重叠的区间
res.push(intervals[i]);
i++;
}
while (i < len && intervals[i][0] <= newInterval[1]) { // 当前遍历是有重叠的区间
newInterval[0] = Math.min(newInterval[0], intervals[i][0]); //左端取较小者,更新给兰区间的左端
newInterval[1] = Math.max(newInterval[1], intervals[i][1]); //右端取较大者,更新给兰区间的右端
i++;
}
res.push(newInterval); // 循环结束后,兰区间为合并后的区间,推入res
while (i < len) { // 在蓝右边,没重叠的区间
res.push(intervals[i]);
i++;
}
return res;
}
func min(a, b int) int {
if a < b { return a }
return b
}
func max(a, b int) int {
if a > b { return a }
return b
}
func insert(intervals [][]int, newInterval []int) [][]int {
res := make([][]int, 0)
l := len(intervals)
i := 0
for i < l && intervals[i][1] < newInterval[0] {
res = append(res, intervals[i])
i++
}
for i < l && intervals[i][0] <= newInterval[1] {
newInterval[0] = min(newInterval[0], intervals[i][0])
newInterval[1] = max(newInterval[1], intervals[i][1])
i++
}
res = append(res, newInterval)
for i < l {
res = append(res, intervals[i])
i++
}
return res
}
复盘总结
考察每个区间,为三种形态的区间安排三次 while 循环,思考每个阶段所需满足的条件,并注意循环结束时的状态。
等号取不取,容易出错,画图看看怎么算有重叠。
合并区间时,新两端更新给蓝区间,无需引入新的变量。
感谢阅读,点赞更棒。
统计信息
通过次数 | 提交次数 | AC比率 |
---|---|---|
92023 | 223019 | 41.3% |
提交历史
提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
---|
相似题目
题目 | 难度 |
---|---|
合并区间 | 中等 |
Range 模块 | 困难 |