Skip to content
FoundationVerified Implementation

Floyd's Cycle-Finding Algorithm (Tortoise and Hare)

Detects cycles and locates the exact cycle entry point in linked lists, functional graphs, or iterated sequences using two pointers moving at 1x and 2x speed in O(1) memory.

Quick Facts

Compact metadata for implementation and discovery.

Category
Searching
Difficulty
Beginner
Family
Two-Pointer / Pointer Cycle Detection
Tier
Foundation
Status
Verified
Review
Source Checked
Sources
1
Formulas
1
Relationships
2
Code example
Ready
Visualization
Ready
Aliases
Tortoise and Hare, Linked List Cycle Detection, Floyd Cycle Detection

Overview

Floyd's Tortoise and Hare algorithm advances a slow pointer by one step and a fast pointer by two steps per iteration. If the linked list or state sequence contains a cycle, the fast pointer laps the slow pointer inside the loop; resetting one pointer to the head and advancing both at 1x speed meets at the exact cycle start node.

Core Concepts

two-pointer speed ratiomodular phase alignmentO(1) space cycle detection

Quick facts

Complexity

Runtime and memory behavior at a glance.

Best

O(n)

Average

O(mu + lambda)

Worst

O(n)

Space

O(1)

Interactive Runtime & Memory Budget Calculator

Estimate wall-clock latency, operation count, and working memory for Floyd's Cycle-Finding Algorithm (Tortoise and Hare) across input scales.

Input Scale N:
JIT-compiled JS/TS (~350M primitive ops/sec)
Est. Average TimeO(mu + lambda)

428.6 µs

60 FPS Frame-Safe (<16ms)~150.0k ops
Est. Worst-Case TimeO(n)

428.6 µs

60 FPS Frame-Safe (<16ms)~150.0k ops
Est. Working MemoryO(1)

128 B

L2/L3 Cache FriendlyN=100,000

When to Use

  • Tortoise and Hare two-pointer cycle detection algorithm that detects a loop in a singly linked list or deterministic state sequence in O(n) time and O(1) pointer memory.
  • Use Floyd's Tortoise and Hare when you need to detect a cycle in a linked list or iterated function using strictly O(1) extra memory.

When Not to Use

  • Avoid it on general graphs with branching out-degree > 1 (use 3-color DFS or Kahn's algorithm instead).

What It Does

  • Advances slow = next(slow) and fast = next(next(fast)) until fast reaches null or slow === fast
  • Rewinds one pointer to the head and steps both 1x to pinpoint the cycle entry index mu and period lambda

Use Cases

  • Detecting loops in singly linked lists in O(1) auxiliary space
  • Detecting periodic cycles in pseudo-random number generators and Pollard's rho factorization
  • Validating functional pointer graphs (out-degree 1) without allocating a visited hash set

Inputs

  • Head pointer of a linked list or successor function f(x) from initial state x0

Outputs

  • Boolean hasCycle, plus cycle start node/index (mu) and cycle length (lambda)

Key Formulas (1)

Meeting Invariant

2(\μ + k) \equiv \μ + k \pmod{\λ} \implies \μ + k \equiv 0 \pmod{\λ}
2(\mu + k) \equiv \mu + k \pmod{\lambda} \implies \mu + k \equiv 0 \pmod{\lambda}

Why rewinding one pointer to the head meets at the cycle entry mu.

Pseudocode

  1. 1.Set slow = head, fast = head
  2. 2.While fast and fast.next exist:
  3. 3. slow = slow.next; fast = fast.next.next
  4. 4. If slow === fast, break (cycle detected)
  5. 5.If no meeting occurred, return { hasCycle: false }
  6. 6.Reset slow = head; while slow !== fast: slow = slow.next; fast = fast.next
  7. 7.Return slow as the exact cycle entry node

Verified Implementation & Unit Tests

Verified Implementation

Tested TypeScript and Python 3 implementations paired with unit tests covering edge cases, duplicate keys, and boundary conditions.

/**
 * Floyd's Tortoise and Hare Cycle Detection — Two-pointer O(1)-space cycle entry (μ) & period (λ)
 * Time: O(μ + λ) | Auxiliary Space: O(1)
 */
export function floydCycleDetection(
  nextIndex: readonly number[],
  head = 0
): { hasCycle: boolean; cycleStart: number; cycleLength: number } {
  const step = (node: number): number => (node >= 0 && node < nextIndex.length ? nextIndex[node] : -1);
  let tortoise = step(head);
  let hare = step(step(head));

  while (tortoise !== -1 && hare !== -1 && tortoise !== hare) {
    tortoise = step(tortoise);
    hare = step(step(hare));
  }
  if (tortoise === -1 || hare === -1) {
    return { hasCycle: false, cycleStart: -1, cycleLength: 0 };
  }

  tortoise = head;
  while (tortoise !== hare) {
    tortoise = step(tortoise);
    hare = step(hare);
  }
  const cycleStart = tortoise;

  let cycleLength = 1;
  hare = step(cycleStart);
  while (hare !== cycleStart) {
    hare = step(hare);
    cycleLength++;
  }
  return { hasCycle: true, cycleStart, cycleLength };
}

Canonical Example

Input
next = [1, 2, 3, 4, 2] (node 4 loops back to node 2)
Output
hasCycle = true, cycleEntry = 2, cycleLength = 3
Explanation
Slow and fast meet inside [2, 3, 4]; phase 2 locates index 2 as the cycle entry.

Implementation Notes

  • After the first meeting inside the cycle, the distance from head to cycle start equals the distance from the meeting point to cycle start modulo lambda.

Common Pitfalls

  • Forgetting to check both fast !== null and fast.next !== null before dereferencing fast.next.next.

Interactive Mechanism Walkthrough & State Debugger

Indexed Interval & Boundary Probe

Tortoise (1x) and Hare (2x) pointers converging inside a linked-list loop.

Target key: 41low=5, mid=4, high=9
4[0]
9[1]
15[2]
22[3]
27[4]
34[5]
41[6]
49[7]
58[8]
63[9]
target41
window [low..high][5 .. 9]
probe mididx 4 (val=27)
comparison27 < 41 (Go Right)
Step 1 of 7: Set slow = head, fast = head
graph-search

Notes

Uses O(1) memory compared to O(n) for a visited HashSet.

Sources (1)

What each reference supports for this entry.

Knuth — The Art of Computer Programming, Vol. 2 (Seminumerical Algorithms)

Book

Attributes the two-pointer cycle-finding method to Robert W. Floyd (1967).

Open source

Explore Next

Good next jumps from the relationship graph, ranked for useful discovery.

SpecializesCycle Detection

Specializes cycle detection to O(1)-space linked lists and functional graphs.

Pollard's rho uses Floyd's cycle finder to detect modular collisions.

Tags

Linked ListCycle DetectionTwo PointersConstant Space