這道題的難度跟微軟的那道面試題相當。
要在集合中插入一段新的集合,相當於求兩個集合的並了。對於新加入一段集合的情況,分為下面幾種:
1. 加入段跟原來的完全相交,也即他的起點和終點都在被包含在原來的段中了。這種情況要合并這之間的段,最終加入段的起點是原來段的起點,終點是原來段的終點。
2. 加入段的起點與原來的相交,終點沒有相交,最終加入的段的起點是起點相交的段的起點,終點是加入段的終點。
3. 加入段的終點與原來的相交,起點沒有相交,最終加入段的起點是加入段的起點,終點是相交段的終點。
4. 加入段與原來的段沒有相交,那麼直接加入加入段。
在實現的時候,判斷相交我用的是二分尋找,對加入段的起點和終點分別尋找,如果找到了的話,標記找到,並返回相交段的編號,否則的話標記未找到,返回應該插入的位置。由於函數介面要求的是返回整個更新後的段,因此除了最終加入段,要把兩頭的那部分沒有影響到的段重新拷貝一下。有關後半段從哪個位置開始拷貝,分兩種情況,如果終點找到了相交段,應該從相交段後面一段開始拷貝,否則的話應該從插入位置的那一段開始。
class Solution {public: pair<int, int> findPos(vector<Interval> &intervals, int pos, int start, int end){ if(start>end) return make_pair(0, start); int mid = (start+end)/2; if(intervals[mid].start<=pos&&pos<=intervals[mid].end){ return make_pair(1, mid); }else if(intervals[mid].start>pos){ return findPos(intervals, pos, start, mid-1); }else if(intervals[mid].end<pos){ return findPos(intervals, pos, mid+1, end); } return make_pair(-1, -1); } vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) { pair<int, int> lr, rr; int msize = intervals.size(); vector<Interval> res; if(msize == 0){ res.push_back(newInterval); return res; } Interval intv(0, 0); lr = findPos(intervals, newInterval.start, 0, msize-1); rr = findPos(intervals, newInterval.end, 0, msize-1); for(int i=0;i<lr.second;i++) res.push_back(intervals[i]); if(lr.first&&rr.first){ intv.start = intervals[lr.second].start; intv.end = intervals[rr.second].end; }else if(lr.first&&!rr.first){ intv.start = intervals[lr.second].start; intv.end = newInterval.end; }else if(!lr.first&&rr.first){ intv.start = newInterval.start; intv.end = intervals[rr.second].end; }else{ intv = newInterval; } res.push_back(intv); int mstart; if(rr.first) mstart = rr.second+1; else mstart = rr.second; for(int i=mstart;i<msize;i++) res.push_back(intervals[i]); return res; }};