- 判断是否有环
- 计算环的长度
- 寻找环的起点
1.判断是否有环
使用两个指针slow和fast。两个指针都从链表的起始处S开始。slow每次向后移动一步,fast每次向后移动两步。若在fast到达链表尾部前slow与fast相遇了,就说明链表有环。 这里可以简单的证明一下:反证法,假如没有环,那么slow永远追不上fast,那么在fast到达链表尾部前slow不会fast相遇了。若相遇了,链表就有环。
2.求环的长度
当slow和fast相遇时,slow和fast必定在环上,所以只要让一者不动,另一者走一圈直到相遇,走过的节点数就是环的长度。
3.求环的起点
如图所示,设AB=n, SA=m。设环的长度为L。
假设都从S点出发,在B点相遇,fast指针的速度为slow速度的2倍。
slow走过的节点数为i:
i = m + n + aL。a为slow绕过的环的圈数。
fast走过的节点数为ki:
2i = m + n + bL 。b为falst绕过的环的圈数。
由于是从S点出发,在B点相遇,所以a和b都为整数(整数倍的L+n的距离,保证a,b为整数).
两者做差有 : i = (b-a) L。
可以得到:m + n = (b-2a)L ,也就是说m + n 为整数倍的L
那么现在将一个指针移动到S点,另一个留在B,让他们都以每次一个节点的速度走
S节点到A走了xL - n的距离,x为某个整数
那么当B节点的指针走到A走了 yL - n的距离,y是不固定整数
所以当S走到A的时候必然会与B走到A时相遇。