一、题目描述
给你一个 无重叠的 ,按照区间起始端点排序的区间列表 intervals,其中 intervals[i] = [starti, endi] 表示第 i 个区间的开始和结束,并且 intervals 按照 starti 升序排列。同样给定一个区间 newInterval = [start, end] 表示另一个区间的开始和结束。
在 intervals 中插入区间 newInterval,使得 intervals 依然按照 starti 升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。
返回插入之后的 intervals。
注意 你不需要原地修改 intervals。你可以创建一个新数组然后返回它。
二、测试用例
示例 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] 重叠。
提示:
0 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 105
intervals 根据 starti 按 升序 排列
newInterval.length == 2
0 <= start <= end <= 105
三、解题思路
- 基本思路:
遍历区间序列,判断好合并和插入的时机。- 合并的时机:只要有重叠就合并
- 插入的时机:首先,插入区间的
starti
要小于遍历到的区间的starti
;其次,插入区间还没有插入过。
- 具体思路:
- 定义:ans 用于存放答案;is_insert 用于判断是否插入,初始化为 false ;
- 遍历区间序列:判断当前区间和插入区间能否合并,能合并则合并;不能则判断插入区间是否可以插入,可以则插入;
- 遍历完,最后还要判断插入区间是否插入,没有则表示插入区间的 starti 是最大的,则插入到区间序列尾部;
- 返回结果 ans 。
四、参考代码
时间复杂度:
O
(
n
)
\Omicron(n)
O(n)
空间复杂度:
O
(
n
)
\Omicron(n)
O(n) 【答案的空间】
class Solution {
public:
bool is_overlap(vector<int>& x, vector<int>& y) {
if (x[0] > y[1] || x[1] < y[0])
return false;
return true;
}
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> ans;
bool is_insert = false;
for (auto& interval : intervals) {
if (is_overlap(interval, newInterval)) {
newInterval[0] = min(interval[0], newInterval[0]);
newInterval[1] = max(interval[1], newInterval[1]);
} else {
if (interval[0] > newInterval[0] && !is_insert) {
ans.push_back(newInterval);
is_insert = true;
}
ans.push_back(interval);
}
}
if (!is_insert) {
ans.push_back(newInterval);
}
return ans;
}
};