Problem

Given a linked list, determine wether or not it has a cycle in it.

Algorithm

The algorithm keeps track of two pointers named tortoise and hare. At each time step, move the tortoise one step forward and the hare two steps forward, and compare the two pointers. If the two pointers point to the same node, then there exists a cycle.

Below is a python implementation of the algorithm:

def floyd(head: Node) -> bool:
    tortoise = hare = head
    while hare and hare.next:
        tortoise = tortoise.next
        hare = hare.next.next
 
        if tortoise == hare:
            return True
    
    return False

This only requires one single pass through the list, hence its time complexity is . Also, the algorithm does not keep an intermediate data structure, and its space complexity is .

Correctness

If the list does not contain a cycle, then it is clear that the algorithm will return False. Thus, it suffices to consider only the case the list contains a cycle.

Let be the length of the preliminary part (before the cycle), and be the length of the cycle. Now, we can label the nodes: the preliminary nodes will be labelled (starting at the head), and the cycle nodes .

At time , the tortoise will be at node , and the hare will be at node . (It has moved nodes; the first nodes is the preliminary part.)

If , tortoise and hare is at the same position, which proves our algorithm. Otherwise if , consider the pointers at time . The tortoise will be at node , and the hare will be at node . Hence both pointers are at the same node, which completes our proof.

References