InsertIntervals

这道也是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;
}
};


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值