Floyd 判圈算法,也称为龟兔赛跑算法,是一种用于检测链表中是否存在环的经典算法。它基于一个简单而巧妙的想法:使用两个指针,一个移动速度为一步(龟),另一个移动速度为两步(兔)。如果链表中存在环,那么这两个指针最终一定会相遇。
以下是 Floyd 判圈算法的详细解释:
-
初始化两个指针:
- 使用两个指针,一个称为 slow,另一个称为 fast。
- 初始时,将 slow 和 fast 指向链表的头节点。
-
移动指针:
- 在每一步中,slow 指针向前移动一步,fast 指针向前移动两步。
-
检测是否存在环:
- 如果链表中不存在环,fast 指针会首先到达链表的末尾(即指向 null)。
- 如果链表中存在环,fast 和 slow 指针会在某个时刻相遇。
-
判断相遇点是否为环的入口:
- 如果 fast 和 slow 指针相遇,说明链表中存在环。
- 此时,将 slow 指针重新指向链表头部,而将 fast 指针保持在相遇点。
- 然后,让 slow 和 fast 指针以相同的速度(都为一步)向前移动。
- 当它们再次相遇时,相遇点即为环的入口。
-
返回结果:
- 如果 fast 和 slow 指针在任何时刻都没有相遇,那么链表中不存在环,返回 false。
- 如果 fast 和 slow 指针相遇,那么链表中存在环,返回 true。
这个算法之所以称为“龟兔赛跑”,是因为可以将两个指针的移动速度比喻为龟和兔的速度,龟兔在不同的速度下移动,最终会相遇。
Floyd 判圈算法的时间复杂度为 O(n),其中 n 是链表的长度。因为两个指针的速度不同,fast 指针每次移动两步,slow 指针每次移动一步,它们最终会在环中相遇,而且在最坏情况下,相遇点距离环的入口的距离不会超过链表的长度,因此算法的时间复杂度是线性的。同时,该算法的空间复杂度为 O(1),因为只使用了两个额外的指针来进行遍历,而不需要使用额外的数据结构。