弗洛伊德(Floyd )使用了两个指针,一个慢指针(龟)每次前进一步,快指针(兔)指针每次前进两步(两步或多步效果是等价的,只要一个比另一个快就行。但是如果移动步数增加,算法的复杂度可能增加)。如果两者在链表头以外(不包含开始情况)的某一点相遇(即相等)了,那么说明链表有环,否则,如果(快指针)到达了链表的结尾(如果存在结尾,肯定无环),那么说明没环。
时间复杂度O(n)
空间复杂度O(1)
假设存在环,A,B分别为快慢指针(A的速度为B的两倍或n倍)y和x分别为链表的环长和非环长。a点和b点分别为链表起点和环形起点。
证明:目标是求得b的位置,即走完ny可以找到环的起点。
先证明y>x(比较易于想象)当B走到b点时,A在环状的与第一圈的b距离为x,与第二圈b距离为y-x,此刻A和B同时出发,那么必定在A与第一圈b距离为y-x相遇,让A从a点重新以一步一格的速度出发。则两点相遇时B走的距离为y-x+x=y刚好走完一圈。
现在证明更普遍的情况(y<x)当B走到b点时,A走了2x,距离第n+1圈的b距离为ny-x。此时B从b点开始,在B距离第一圈的b距离为ny-x时两点相遇,把A挪到a点出发,以一步一格速度走,当A走完x时,B走了ny-x+x。刚好在b点的位置。