您的位置:首页 > 其它

57. Insert Interval

2016-04-22 15:21 477 查看
这道题有三种解法,其中两种跟上一题,merge interval有些相似。

1.直接把新的区间接在区间列表的后面,然后sort,merge interval。这么简单就不贴代码了。

2. 从前往后遍历已知的区间集合,当找到第一个起始位置大于要插入区间起始位置的元素的时候,插入新的区间。然后按照merge interval的方法改变上一个插入的区间,或者插入新的区间。这个做法徐杰实现有挺多地方要注意的。比如第一个插入的是新区间怎么办,新区间和很多已有的区间都有重合怎么办,要插入的跟在最后,和所有的都没有重合怎么办。vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
sort(intervals.begin(), intervals.end(),[](const Interval& left,
const Interval& right){return left.start<right.start;});
vector<Interval> res;
bool used=false;
for(int i=0;i<=intervals.size();++i){
if(used&&i==intervals.size())
break;
Interval nextit;
if(used==false&&(i==intervals.size()||intervals[i].start>newInterval.start)){
nextit=newInterval;
used = true;
i--;
}
else{
nextit=intervals[i];
}
if(res.empty()||res.back().end<nextit.start)
res.push_back(nextit);
else
res.back().end=max(res.back().end,nextit.end);
}
if(res.empty())
res.push_back(newInterval);
return res;
}第2和第一种解法在lc运行的时候,时间上没有特别本质的差别,大概差了30几ms。但是如果先前给的区间序列是排好序的话,那么第二种解法的有点就体现出来了。第一种解法需要排序,所以复杂度是O(nlogn),
第二种是O(n)。
在网上还流传着第三种解法。和第二种解法的区别之处是,只要插入了res数组的元素就不发生变化了。在便利给定区间集合的过程中,如果当前区间和新区建有交集,那么改变新的区间。直到遇见和新区建没有交集的区间,再把经过很多次更改的新区间放到数组里。之后所有的区间直接copy。

我直接复制的这位同学的代码 http://bangbingsyb.blogspot.com/2014/11/leetcode-insert-interval.html 有时间了我自己照猫画虎,看看能不能写出来

vector<Interval> insert(vector<Interval> &intervals, Interval newInterval) {
vector<Interval> ret;
bool isInsert = false;
for(int i=0; i<intervals.size(); i++) {
// already insert newInterval
if(isInsert) {
ret.push_back(intervals[i]);
continue;
}

// insert newInterval before current interval
if(newInterval.end < intervals[i].start) {
ret.push_back(newInterval);
ret.push_back(intervals[i]);
isInsert = true;
continue;
}

// combine newInterval with current interval
if(newInterval.start<=intervals[i].end && intervals[i].start<=newInterval.end) {
newInterval.start = min(newInterval.start, intervals[i].start);
newInterval.end = max(newInterval.end, intervals[i].end);
continue;
}

// newInterval after current interval
ret.push_back(intervals[i]);
}

if(!isInsert) ret.push_back(newInterval);
return ret;
}

当然了,这道题也有空间复杂度是常数的解法。思路基本和上一中解法相同,插入新区建,一直删除之后和他相交的,在这个过程中更新前后界。但是问题还是一样,如果遇见就集合是[[2,3],[4,5],[5,6],....,[1001,1002]]这样的区间,而插入的新区间是[1,1002],就要删除好多元素,复杂度就很高了。
vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
vector<Interval>::iterator it = intervals.begin();
while(it!= intervals.end())
{
if(newInterval.end<it->start)
{
intervals.insert(it, newInterval);
return intervals;
}
else if(newInterval.start > it->end)
{
it++;
continue;
}
else
{
newInterval.start = min(newInterval.start, it->start);
newInterval.end = max(newInterval.end, it->end);
it =intervals.erase(it);
}
}
intervals.insert(intervals.end(), newInterval);
return intervals;
}

as expected, lc 超时额
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: