1 原问题
问题:给一个单向链表,判断这个链表中是否有环。并找到这个环的起点。
解法:
(1)使用两个指针,一个快一个慢,快的每次循环向后移动两步,慢的每次向后移动一步,如果两个指针相遇,则链表存在循环。
(2)让一个指针从相遇点出发,每次向后移一步,另一个指针从链表头出发,每次也向后移一步,两个指针相遇的点就是环的起点。
2 证明
我们要证明的不是 b = c, 而是两个速度相同的指针分别从O点和P点顺时针出发,它们会在Q点相遇。
先行条件是快慢指针在P点相遇,且快指针速度是慢指针的2倍,则相遇时,快指针走过的路径长度是慢指针的2倍
解: 设快慢指针在P点相遇时,慢指针在圆圈中走了m圈, 快指针走了n圈。
则有:
2[c + m(a + b) + a] = c + n(a + b) + a (1)
<=> c = (n - 2m - 1) (a+b) + b (2)
如果 (n - 2m - 1) = 0,(2)式变成 c = b,得证。
如果 (n - 2m - 1) < 0,(2)式可以推出 c < 0,不可能。
如果 (n - 2m - 1) > 0,由公式(2)我们可以知道,c刚好等于(整数倍周长 + b) ,如果一个指针在P点出发,一个在O点出发,当从O出发的指针到达Q点时,从P出发的指针刚好走了一个b + 整数倍的周长,然后出现在Q点,从而可知两个指针在Q点相遇,得证。