有环链表找交叉点的数学公式

                         有环链表找交叉点的数学公式

题目

已知一个链表有环,要求找到交叉点。

算法

用2个指针,一快一慢,快指针每次走2步,慢指针每次走一步。当二者交汇时,将快指针拉回起点,然后快指针也每次走一步,当二者下次交汇时即为交叉点。

数学公式 

先看示意图如下:

定义:A为链表起点,B为交叉点,C为快慢指针第一次交汇点,D为慢指针第一次到达B点时快指针的位置,k为第一次交汇时快指针在环内所走圈数,定义圈长为e,指针绕圈均顺时针移动。同时线段长度定义如图。

可知:

  • b=d

因为,当慢指针到达B时,快指针在D,快慢指针的距离为d,快指针需要d步才能追上慢指针,因为每走一步,快慢指针的距离会减1。走了d步之后,快慢指针到达C,而慢指针走的距离为b,也即b=d。

如果要搞得复杂一点,设C为慢指针第一次到达A时快指针的位置,D为第一次交汇的位置,此时快慢指针的距离为d+c。顺时针方向快指针去追慢指针。交汇后,快指针走了2*(d+c),慢指针走了b+c,于是2*(b+c)=2*(d+c)。b=d同样得证。

  • 2*(a+b)=k*(2*b+c)+b+a \Rightarrow a=k*e-b

左侧表示慢指针所走步数乘以2。右侧表示k圈的长度加上a加上b,即快指针所走步数。由于b=d,所以圈长e=2×b+c。将这个公式变换一下可得,a+b=k*e。也即a+b是圈长的若干倍。得出如下公式。

a=k*e-b。

此时,2个慢指针均每次走1步,一个从A出发,一个从C出发。当从A出发的指针走了a距离到达B后,从C出发的指针走了k圈然后往回拉了b的距离也正好在B点。

算法思路得以证明。

猜你喜欢

转载自blog.csdn.net/junbujianwpl/article/details/81587767