给你一个 无重叠的 ,按照区间起始端点排序的区间列表 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 <= 10^4
intervals[i].length == 2
0 <= starti <= endi <= 10^5
intervals
根据starti
按 升序 排列newInterval.length == 2
0 <= start <= end <= 10^5
解法一:
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
vector<vector<int>> result; // 结果列表
int i=0; // 计数变量
// 将所有和新区间没有重叠的区间加入结果列表
while(i<intervals.size()&&intervals[i][1]<newInterval[0]){
result.push_back(intervals[i]);
i++;
}
// 合并所有和新区间有重叠的区间
while(i<intervals.size()&&intervals[i][0]<=newInterval[1]){
newInterval[0]=min(intervals[i][0],newInterval[0]);
newInterval[1]=max(intervals[i][1],newInterval[1]);
i++;
}
result.push_back(newInterval); // 将合并后的新区间加入结果列表
// 将剩下的区间加入结果列表
while(i<intervals.size()){
result.push_back(intervals[i]);
i++;
}
return result;
}
};
- 将所有和新区间没有重叠的区间加入结果列表;
- 合并所有和新区间有重叠的区间,得到合并后的新区间;
- 将剩下的区间加入结果列表。
解法二:
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals,
vector<int>& newInterval) {
int left = newInterval[0], right = newInterval[1]; // 新区间的起始和结束位置
bool placed = false; // 新区间是否已经被放置的标志
vector<vector<int>> result; // 结果列表
for (const auto interval : intervals) {
if (interval[0] > right) { // 当前区间的起始位置在新区间的右侧,将新区间插入到当前区间的右侧
if (!placed) { // 如果新区间还没有被放置,将新区间插入到结果列表中
result.push_back({left, right});
placed = true;
}
result.push_back(interval); // 将当前区间加入结果列表
} else if (interval[1] < left) { // 当前区间的结束位置在新区间的左侧,将当前区间加入结果列表
result.push_back(interval);
} else { // 当前区间和新区间有重叠,合并区间
right = max(interval[1], right); // 更新新区间的结束位置
left = min(interval[0], left); // 更新新区间的起始位置
}
}
if (!placed) // 如果新区间还没有被放置,将新区间插入到结果列表中
result.push_back({left, right});
return result;
}
};
- 如果当前区间的起始位置在新区间的右侧,将新区间插入到当前区间的右侧,同时将当前区间加入结果列表;
- 如果当前区间的结束位置在新区间的左侧,将当前区间加入结果列表;
- 如果当前区间和新区间有重叠,合并区间,更新新区间的起始和结束位置;
- 如果新区间还没有被放置,将新区间插入到结果列表中。