题目来源
题目描述
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
}
};
题目解析
分析数据
- 数据量最大 1 0 4 10^4 104,所以算法复杂度不要超过 O ( N 2 ) O(N^2) O(N2)
- 一定是两行,一定形成了有效区间。而且区间比较大
- 升序。能不能利用单调性呢?
思路
用指针去扫intervals,最多可能有三个节点
- 不重叠的绿区间,在蓝区间的左边
- 有重叠的绿区间
- 不重叠的绿区间,在蓝区间的右边
分析:
- 不重叠
- 需要满足:绿区间的右端,位于蓝区间的左边,比如
[1, 2]
- 怎么处理
- 则当前绿区间,推入res数组,指针+1,去考察下一个绿区间
- 循环结束时,当前绿区间的尾部,没有落在当前的蓝区间之前,有重叠了,比如
[3, 5]
- 需要满足:绿区间的右端,位于蓝区间的左边,比如
- 有重叠,需要满足什么呢?
- 反过来想,不重叠,需要满足:绿区间的右端 < 蓝区间的左端
- 因此,有重叠,需要满足:绿区间的左端 <= 蓝区间的右端(三块绿色[3,5], [6,7], [8, 10]的共性)
- 怎么处理呢?
- 和蓝有重叠的区间,会合并成一个区间:左端取蓝绿左端的较小者,右端取蓝绿区间的较大者,不断更新蓝区间
- 循环结束时,将蓝区间(它是合并后的新区间)推入 res 数组。
- 剩下的,都在蓝区间右边,不重叠。不用额外判断,依次推入 res 数组。
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> ans;
int len = intervals.size();
int i = 0;
// 判断左边不重合
while (i < len && intervals[i][1] < newInterval[0]){
ans.emplace_back(intervals[i]);
i++;
}
// 判断重合
while (i < len && intervals[i][0] <= newInterval[1]){
newInterval[0] = std::min(intervals[i][0], newInterval[0]);
newInterval[1] = std::max(intervals[i][1], newInterval[1]);
i++;
}
ans.emplace_back(newInterval);
// 判断右边不重合
while (i < len && newInterval[1] < intervals[i][0]){
ans.emplace_back(intervals[i]);
i++;
}
return ans;
}
};