算法设计与分析第十五周——Insert Interval
题目详情
题目链接:57. Insert Interval
题目大意:给定一个含有 n 个互不相交的区间的集合,此时,再往这个区间集合里添加一个区间,如果因此产生了某些区间部分或全部的重合,则进行归并整合,返回得到的最后的没有相交的区间的集合。
样例分析:
输入区间集合 | 新加区间 | 结果 | 分析 |
[ [1, 3], [6, 9] ] | [2, 5] | [ [1, 5], [6, 9] ] | 因为区间 [2, 5] 的 [2, 3] 部分与区间集合中的区间 [1, 3] 的 [2, 3] 部分重合,故归并整合得到一个新区间 [1, 5] |
[ [1,2],[3,5],[6,7],[8,10],[12,16] ] | [4,8] | [ [1, 2], [3, 10] [12, 16] ] | 区间 [4, 8] 与[3,5],[6,7],[8,10] 均有交集,所以整合得到新区间 [3, 10] |
题目分析与算法设计
根据题目含义,我们可以把区间的情况分为两种:
- 插入区间与集合原有区间无交集;
- 插入区间与集合原有区间有交集;
无交集情况时,直接将新区间插入到对应的位置即可。
有交集的情况比较复杂,定义一个区间在另一个区间的左边即为该区间的尾端小于另一个区间的前端,遍历集合区间,对于那些与将要插入的区间无交集的并且在它左边的区间,先记录下来,对于有交集的区间,与将要插入的区间作对比,更新插入区间的前端为比较两方区间的前端最小者,同时更新插入区间的尾端为比较两方区间的尾端最大者,最后再把区间集合中在将要插入的区间右边的区间记录下来,即可得到最终结果,其中,维护一个集合来记录输出结果,维护一个下标变量来遍历已给的集区间集合。
代码详情
vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
int len = intervals.size();
int curr = 0;
vector<Interval> ans;
// deal the intervals without conflict
while (curr < len && intervals[curr].end < newInterval.start) {
ans.emplace_back(intervals[curr]);
++ curr;
}
// deal with intervals with conflict
while (curr < len && intervals[curr].start <= newInterval.end) {
newInterval.start = min(newInterval.start, intervals[curr].start);
newInterval.end = max(newInterval.end, intervals[curr].end);
++ curr;
}
ans.emplace_back(newInterval);
// deal with those left
while (curr < len) {
ans.emplace_back(intervals[curr]);
++ curr;
}
return ans;
}
时间复杂度为O(n),空间复杂度也为O(n)。
谢谢阅读。