Floyd’s Cycle Detection (Tortoise and Hare)

Suppose we have a simple linked list and want to determine whether it contains a cycle. The most straightforward solution would be to traverse the linked list and store the values you see. If you ever see the same value twice, then there must be a loop. Otherwise, if you get through the entire list without seeing the same value twice, then there are no cycles. This works perfectly well, but it uses linear memory to remember the visited nodes.

(Image Credits: Eppstein, David. Wikimedia.org, 2025, upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Tortoise_and_hare_algorithm.svg/1280px-Tortoise_and_hare_algorithm.svg.png. Accessed 22 Feb. 2026.)

Floyd’s Cycle Detection Algorithm takes a different approach. Rather than remembering the past, it uses two pointers moved at different speeds to infer a cycle. The idea is actually quite fun: One pointer (the tortoise) moves one step at a time; the other (the hare) moves two steps at a time. If the list has no cycle, the hare will eventually hit the terminal value. But, if there is a cycle, something more interesting happens. In this case, the tortoise and hare won’t be able to escape the loop and so they’ll just keep doing laps. But the hare moves one step faster than the tortoise, meaning that their cyclical distance decreases by 1 each iteration. The situation is like two runners on a circular track: even if they start at different positions, the faster runner will eventually lap the slower one. And when that happens, they’ll occupy the same position, and we’ll know there’s a cycle.

There’s something satisfying about the “economy” of the approach. We don’t need to track where we’ve been when we can let the structure of the list reveal itself through the motion of two pointers moving at different speeds: a loop would trap both pointers, in which case their difference in speed guarantees a collision.

class Node:
    next: Node

def step(node: Node) -> Node | None:
    if node is None:
        return None
    return node.next

def floyd(head: Node) -> bool:
    tortoise = step(head)
    hare = step(step(head))

    while hare is not None and hare is not tortoise:
        tortoise = step(tortoise)
        hare = step(step(hare))
    
    if hare is None:
        return False  # hare exited list; no cycle
    return True       # hare = tortoise; cycle

Resources

  • “Cycle Detection.” Wikipedia, 15 Feb. 2022, en.wikipedia.org/wiki/Cycle_detection#Floyd. Accessed 22 Feb. 2026.
  • —. “Floyd’s Cycle Finding Algorithm.” GeeksforGeeks, 24 Jan. 2022, www.geeksforgeeks.org/dsa/floyds-cycle-finding-algorithm/. Accessed 22 Feb. 2026.

3 responses

  1. Karan Avatar

    Great explanation! I really like how you used the circular track analogy to make Floyd’s algorithm intuitive and easy to visualize. The emphasis on its efficiency detecting a cycle without extra memory highlights the elegance of the approach. It’s a perfect example of how understanding structure can replace brute-force tracking.

  2. Shreya S Avatar

    Loved how you contrasted the simple store visited nodes approach with the more elegant tortoise‑and‑hare method. The concise Python example ties perfectly to your explanation.

  3. Sung Ahn Avatar

    Brother, you already have a job. Why are you putting leetcode

Leave a Reply to Karan Cancel reply

Your email address will not be published. Required fields are marked *