【链表1】有关链表环的各种问题

来源:互联网 发布:装修平面设计软件 编辑:程序博客网 时间:2024/06/03 20:50

==小记==

以前只研究过如何判断一个链表是否有环,结果百度三面的时候SB了,因为关链表环有各种各样的问题

【问题1】如何判断一个链表是否有环

这个问题人人都知道答案,但是下面两个问题呢?

【问题2】如何选择两个指针的步长

【参考链接】http://jishu.zol.com.cn/6357.html

设步长分别为x和y,链表回环结点数为n,非环结点数为为m,经过t次跨步,则只要xt和yt对n同余并且xt和yt都大于m就可以相遇(假设x>y)

xt-yt=pn(p为1~正无穷的所有整数)

yt>m

t=pn/(x-y) > m/y(只需pn可整除(x-y))

指针移动次数为(x+y)t=(x+y)/(x-y)*pn

而要想pn永远整除(x-y),因为p的取值为1到正无穷,所以总会存在那个p,是的pn乘除(x-y),所以x、y可以取任意值,但是最简单的方法x-y=1即可。在x-y固定为1的情况下x+y越小,则移动次数越少,也即指针比较次数越少,所以最优情况下设x为2,y为1。

【问题3】链表环的起点在哪

【参考链接】http://www.douban.com/note/172176904/

步骤一:两个指针从head开始,一个以1为步长(记为p),一个以2为步长(记为q)遍历链表。当他们在某一时刻相等时,说明q走了超过p所走的环的长度的整数倍。

L0:非环部分的长度。

L1:环部分的长度。

offset:相遇时离开环首地址的偏移长度。

则p的指针共走了L0+ML1+offset的长度,其中M是>=0的整数。

q指针走过了2(L0+NL1+offset)的长度,且他们相差L1的整数倍,即L0+ZL1+offset=0。

重写为:L0=ZL1-offset(Z为任意整数)

步骤二:将q再次指向链表head,并以步长为1向前遍历,同时p也继续步长为1向前遍历。两个指针再次相遇时,就是环的首节点。

证明:q在步骤二中走了L0到环首地址,而L0=ZL1-offset,因此p可以认为走了ZL1-offset,此时也到了环首地址。





原创粉丝点击