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]
.
Subscribe to see which companies asked this question
分析:
和Leetcode 56 Merge Intervals这道题类似,这道题多了一点,需要将一个新区间插入到给定的区间集合中。
区间集合已排好序。
如果新区间与原集合重合了,那么合并。
解法1:
最容易想到的方法就是 将新区间插入到原集合 然后按照Merge Interval的方法 排序 合并。。
当然这也做是可以实现的 只不过效率并不高 因为给定的区间集合已经排好序了。。
我们需要好好利用这个条件。
下面也给出解法1的代码(已AC 2016-03-28):
vector<Interval> insert(vector<Interval>& v, Interval newv) { if (v.size() <= 0) { vector<Interval> res; res.push_back(newv); return res; } v.push_back(newv); // 先按照start从小到大排序 sort(v.begin(), v.end(), cmp); vector<Interval>::iterator it = v.begin(); int st = (*it).start, ed = (*it).end; vector<Interval> res; for (; it != v.end(); ++it) { // 除去最后一个区间 if ((it + 1) != v.end()) { // 区间不能合并 if ((it + 1)->start > ed) { res.push_back(Interval(st, ed)); st = (it + 1)->start; } // 要比较区间的结束 有可能出现[1 5] [2 4] 这样区间结束是较大者 ed = ((it + 1)->end > ed) ? (it + 1)->end : ed; }// end if // 最后一个区间单独考虑 else { if (it->start > ed) { res.push_back(Interval(st, ed)); res.push_back(*it); }//end if else { ed = ((it)->end > ed) ? (it)->end : ed; res.push_back(Interval(st, ed)); }//end else }//end else }//end for return res; }
这种解法的思路是定位新区间的位置。
只有当新区间与集合中的区间重合时,我们需要先进行合并。直至没有区间重合。
下面给出没有区间重合与区间重合的条件
假定新区间为:[newSt, newEd]
集合中区间为:[St, Ed]
无重合:
Ed < newSt (集合区间在新区间左侧)
St > newEd (集合区间在新区间右侧)
重合:
Ed >= newSt or St <= newEd
【上面等号的情况也包括】
另外需要注意的是合并区间之后,合并后区间的端点值需要更新。【取较大值】
下面给出解法2的代码(已AC 2016-03-28):
vector<Interval> insert(vector<Interval>& v, Interval newv) { vector<Interval> res; if (v.size() <= 0) { res.push_back(newv); return res; } int i = 0, sz = v.size(); // 找到区间插入的位置 for (; i < sz && v[i].end < newv.start; ++i) res.push_back(v[i]); if (i == sz) { res.push_back(newv); return res; } newv.start = (v[i].start < newv.start) ? v[i].start : newv.start; // 区间重合 需要先进行合并 for (; i < sz && v[i].start <= newv.end; ++i) newv.end = (v[i].end > newv.end) ? v[i].end : newv.end; res.push_back(newv); // 如果还有未重合的区间 for (; i < sz; ++i) res.push_back(v[i]); return res; }