这道也是4*题,思路基本和Merge一致,小的地方稍微要改改。
我已开始打算二分找到start的插入位点,结果发现找不到的时候,返回的插入位点坐标是什么,low?high?low+-1,high+-1?说明二分查找还是没有完全掌握,包括编程之美也出过二分的几个变形,感觉难度还是有点大。另外编程珠玑也多次提到,只有极少的程序员能完整写对二分,更不要说各种变形了= = 这块后面再搞一搞
于是还是linklist提高插入删除效率,找位点只有遍历了,主要是二分找不到时不知道哪个是位点,再次印证一点,先写框架逻辑,在注重细节,当然可能想大框架时,可能有些细节变量灵光一现要立马记录下来。代码可能有部分有冗余,但是不高兴去优化了。从这里总结经验,找指针NULLbug从后往前找,看每个p->next p->val立马 p是否有NULL,然后再网上,p->next->next则看p->next是否有空,一直回溯上去,对于NULL的另外处理,这样就不会有指针bug了,按照这个思路,我出现指针bug的频率比最初学C++少了特别多,然后里面处理merge还漏掉了几个interval包含另一个的情况。。。因为直接调用前面写的ShouldMerge还要判断两个是否交换,比较麻烦,而且效率不高
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* Interval() : start(0), end(0) {}
* Interval(int s, int e) : start(s), end(e) {}
* };
*/
struct Node
{
Interval interval;
Node* next;
};
class Solution {
public:
Node* CreateLinkList(vector<Interval> data)
{
Node* head=NULL;
head=new Node();
head->interval=data[0];
head->next=NULL;
Node* rail=head,*p;// record each rail
for(int i=1;i<data.size();i++)
{
p=new Node();
p->interval=data[i];
p->next=NULL;
rail->next=p;
rail=rail->next;
}
return head;
}
vector<Interval> insert(vector<Interval> &intervals, Interval newInterval)
{
/*
int low=0,high=intervals.size()-1;
while(low<=high)
{
int mid=(low+high)/2;
if(intervals.at(mid).start<newInterval.start)
low=mid+1;
else if (intervals.at(mid).start>newInterval.start)
high=mid-1;
else
;
}
//assume i-1 is lower than query, i is larger than query, if not found
*/
if(intervals.size()==0)
{
intervals.push_back(newInterval);
return intervals;
}
//copy to linklist
Node* head=CreateLinkList(intervals);
Node*p=head,*prev=NULL;
while(p!=NULL&&p->interval.start<newInterval.start)//find insert pos try to convert to binary search
{
prev=p;
p=p->next;
}
if(prev==NULL)//insert to head, no last loop
{
Node* newnode=new Node;
newnode->interval=newInterval;
head=newnode;
newnode->next=p;
p=newnode;
}
else if(prev->interval.end>=newInterval.start)//merge prev and new Interval
{
Interval mergedn;
//ShouldMerge(prev->interval,newInterval,mergedn);
if(prev->interval.end<=newInterval.end)
{
mergedn.start=prev->interval.start;
mergedn.end=newInterval.end;
}
else
{
mergedn=prev->interval;
}
prev->interval=mergedn;
p=prev;
}
else//insert newInterval
{
Node* newnode=new Node;
newnode->interval=newInterval;
prev->next=newnode;
newnode->next=p;
p=newnode;
}
while(p->next!=NULL)//loop until p->end <p->next->start, merge p and pnext
{
if(p->interval.end>=p->next->interval.start)
{
//merge newinterval and p replace p
Interval mergedn;
if(p->interval.end < p->next->interval.end)
{
//ShouldMerge(newInterval,p->interval,mergedn);
mergedn.start=p->interval.start;
mergedn.end=p->next->interval.end;
}
else
{
mergedn=p->interval;
}
p->interval=mergedn;
p->next=p->next->next;
}
else//break;
{
break;
}
}
//copy linklist to vector;
p=head;
intervals.clear();
while(p!=NULL)
{
intervals.push_back(p->interval);
p=p->next;
}
return intervals;
}
};