leetcode第一刷_Insert Interval
阿新 • • 發佈:2019-04-22
難度 sta 找到 ack 微軟 rt+ popu 應該 star
這道題的難度跟微軟的那道面試題相當。
要在集合中插入一段新的集合,相當於求兩個集合的並了。對於新增加一段集合的情況,分為以下幾種:
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; } };
leetcode第一刷_Insert Interval