这道题就是区间插入问题,目前看到的解法主要有三种,一种是直接分析区间重叠,具有O(n)时间和O(n)空间复杂度,另一种是用二叉搜索树来做,还有一种是借助了STL库中的equal_range方法来做,写法比较优雅。这篇博客主要给出第一种解法和第三种解法的代码
题目
Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).
You may assume that the intervals were initially sorted according to their start times.
Example 1:
Given intervals[1,3],[6,9]
, insert and merge[2,5]
in as[1,5],[6,9]
.Example 2:
Given[1,2],[3,5],[6,7],[8,10],[12,16]
, insert and merge[4,9]
in as[1,2],[3,10],[12,16]
.This is because the new interval
[4,9]
overlaps with[3,5],[6,7],[8,10]
.
分析区间重叠
博主的解是分析区间重叠的,速度是16ms。四个if的意思是,
- 如果该原区间与插入区间不重叠,则将原区间保留
- 中间两个for循环:如果该原区间与插入区间部分重叠,则将插入区间拓展,并删除原对应区间
- 如果原区间包含了插入区间,则直接返回(因为插入和没插入效果一样)
最后要按照顺序把区间摆好,如果没有约定拜访顺序的话,输入也是要做检查的。
struct Interval{ int start; int end; Interval() : start(0), end(0) {} Interval(int s, int e) : start(s), end(e){} }; class Solution { public: vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) { vector<Interval> result; // check for (auto &interval : intervals){ if (interval.start > newInterval.end || interval.end < newInterval.start){ result.push_back(interval); } else if (interval.start < newInterval.start && interval.end >= newInterval.start && interval.end <= newInterval.end){ newInterval.start = interval.start; } else if (interval.start >= newInterval.start && interval.start <= newInterval.end && interval.end > newInterval.end){ newInterval.end = interval.end; } else if (interval.start <= newInterval.start && interval.end >= newInterval.end){ return intervals; } } const int len = result.size(); for (int i = 0; i < len; ++i){ if (result[i].start > newInterval.start){ result.insert(result.begin() + i, newInterval); return result; } } result.push_back(newInterval); return result; } };
借助STL库equal_range
推荐的优雅的答案,速度12ms,核心还是equal_range方法的使用
class Solution { public: vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) { auto compare = [] (const Interval &intv1, const Interval &intv2) { return intv1.end < intv2.start; }; auto range = equal_range(intervals.begin(), intervals.end(), newInterval, compare); auto itr1 = range.first, itr2 = range.second; if (itr1 == itr2) { intervals.insert(itr1, newInterval); } else { itr2--; itr2->start = min(newInterval.start, itr1->start); itr2->end = max(newInterval.end, itr2->end); intervals.erase(itr1, itr2); } return intervals; } };