给定一个单链表:
- 如何判断单链表是否有环?
- 如何找出环的连接点在哪里?
- 如何知道环的长度?
转载请注明出处。
单链表如上图所示。
1. 设置两个指针同时遍历链表,一个指针步长为1(V),另一个步长为2(2V)。当这两个指针相遇时,单链表有环。
假设链表头元素为A,环的连接点为B,链表头到环连接点的长度为L,环长度为S,
则,当V到达B时,2V到达D,B->D长为L mod S,D->B长为S - L mod S,
问题转化成了在环内的追逐,
在环中,2V指针要追S - L mod S这么多距离,才能碰到V,2V和V的相对速度为1,
所以从环内开始,指针相碰所用的时间为 (S - L mod S) / 1
这段时间内,2V前进了2(S - L mod S),V则从B到C,前进了(S - L mod S),两者碰于C点。
2. 两个步长为1的指针分别从链表首节点A和碰撞点C开始向前遍历,当两者相遇时,该节点即为环的连接点B。
B->C长为(S - L mod S),C->B长为L mod S。
当L<=S时,L mod S = L,所以 A->B = C->B = L,两者相等,必定相遇于B点;
当L>S时,假设Floor( L / S ) = i,则当从C开始遍历的指针第i+1次经过B点时相遇;
3. 从碰撞点C开始,2个指针又以不同的速度追逐,当再次相遇时,V经过的步长即为环长
因为相对速度为1,2V要追赶环长S的距离赶上V,所以这段时间内V刚好走过S。