linklist Qsort

后来再看题目发现要求是常数空间复杂度,但是实际上mergesort也过了,也可能是只加了一个数组的缘故。

qsort其实比mergesort在链表上更好实现,但是还是需要便利一遍找tail指针,这次是常数空间,然而却TLE了。。。。

要么是lumoto版本导致比较次数多了,但是hoare真心有点记忆感觉。还是说递归的原因,但是mergesort也是递归都没超时,不解啊。。


另外今天还和高富帅考虑qsort的非递归算法的问题。


void qsort(ListNode* low, ListNode* high)
{
	if(low==high || (high!=NULL&&high->next==low)) return;
	else
	{
	    int x=0;
		ListNode *p=new ListNode(x);
		p->next=low;

		ListNode *i=p,*j;
		for(j=low;j!=high;j=j->next)
		{
			if(j->val<high->val)
			{
				i=i->next;
				swap(i->val,j->val);
			}
		}
		swap(i->next->val,j->val);
		//int tmp=i->next->val;
		//i->next->val=j->val;
		//j->val=tmp;
		//Swap(i->next->val,j->val);
		qsort(low,i);
		qsort(i->next->next,high);

		delete p;
	}
}

ListNode* sortList(ListNode* head)
{
	if(head==NULL||head->next==NULL) return head;
	ListNode*p=head;
	while(p->next!=NULL)
		p=p->next;
	qsort(head,p);
	return head;
}
而且里面由于之前从while改成for循环,我又受fwaks大神的影响,习惯了for里面定义变量,变量近一点确实好,但是外面的忘记删了,关键是compiler还不提醒= =于是就悲剧了。。。我还到群里找各路找问题,一直以为不能交换值是因为不是左值,但是那明显是左值。。。


所以代码还是要仔细,还是建议for里面写比较好,变量离得近一点,除非像上面,在loop外还要用,才把他改过来。

另外提到一个二分查找自己的不解,例如找一个元素,如果出现多次,返回index最小的,后来和高富帅讨论,可以找到后加一点判断就可以了,如果左边一个不等mid,就返回,说明一点是最小的index,如果相等,这high=mid-1 这继续找。一定会定位到的。大概是这样,没有严格的证明正确,也没找到OJ的题来测。照这样,找最大index的题目也可以做了,这是编程之美改错题的两小问。

int BinarySearch(int low, int high, double x,double *a)
{
	while(low<=high)
	{
		int mid=(low+high)/2;
		if(a[mid]<x)
		{
			low=mid+1;
		}
		else if(a[mid]>x)
		{
			high=mid-1;
		}
		else
		{
			if(a[mid-1]!=x)
				return mid;
			else
			{
				high=mid-1;
			}
		}
	}
	return -1;
}

稍改一下,返回最大index

int BinarySearch(int low, int high, double x,double *a)
{
	while(low<=high)
	{
		int mid=(low+high)/2;
		if(a[mid]<x)
		{
			low=mid+1;
		}
		else if(a[mid]>x)
		{
			high=mid-1;
		}
		else
		{
			if(a[mid+1]!=x)
				return mid;
			else
			{
				low=mid+1;
			}
		}
	}
	return -1;
}

另外看了另外两问,返回<x 的最大index,如果x不存在,最后一定是[low, high] 其中high=low+1 从二分的查找树可以看出,然后mid=(low+mid)/2=low, 所以返回low-1 或high-1, 如果找得到的话,考虑返回=x的最小index的前一个index,所以上面代码2 while出口加上 return low(high)-1, 然后里面找到case返回,return mid-1。 返回最小的i使得a[i]>v

同理,在代码3按照上述一样修改即可。可惜编程之美没找到答案,然后也没有OJ测。


另外又回顾了一遍建堆时间复杂度,感觉不要参照算导会容易变成自己真正消化的东西。

调整次数: 1*(h-1)+2*(h-2)+2^(h-2)*1=h*(1+2+2^2+...2^(h-2))- (1*1+2*2+2^2*3+...2^(h-2)*(h-1))

后面是等差乘等比,用下公式,前面等比求和,最后算出来 O(2n)=O(n), 其中h~logn), 比算导那么繁琐的好理解。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值