Table of Contents
1139 words
6 minutes
Detecting a Cycle in a Singly Linked List and Finding Its Start: Floyd's Cycle Detection Algorithm

Problem Description#

Subproblem 1: Determine Whether a Linked List Contains a Cycle#

Given the head node head of a singly linked list, determine whether a cycle exists in the linked list. If there is a node in the linked list that can be reached again by continuously following the next pointer, then a cycle exists in the linked list.

Input: head = 3→2→0→-4
↑_______↓
Output: true

Subproblem 2: Find the Starting Point of the Cycle#

Building on the previous problem, if a cycle exists, return the entry node of the cycle.

Input: head = 3→2→0→-4
↑_______↓
Output: node 2
Explanation: the entry of the cycle is node 2

Solution Approach#

Phase 1: Floyd’s Cycle Detection (Determine Whether a Cycle Exists)#

Use fast and slow pointers: slow moves one step at a time, fast moves two steps at a time.

  • If the linked list has no cycle: fast will reach null first, and we determine there is no cycle
  • If the linked list has a cycle: fast and slow will definitely meet in the cycle (just like on a circular track, the faster person will always lap the slower person)

Phase 2: Find the Entry of the Cycle (Mathematical Derivation)#

After fast and slow meet in the cycle:

  1. Point slow back to the head of the linked list
  2. slow and fast advance at the same speed (one step at a time)
  3. The node where they meet again is the entry of the cycle

Mathematical Proof#

Let:

  • The distance from the head of the linked list to the cycle entry be a
  • The distance from the cycle entry to the first meeting point be b
  • The length of the cycle be L, then the remaining distance from the meeting point to the cycle entry is c = L - b

At the first meeting:

  • slow has walked a + b steps
  • fast has walked a + b + n·L steps (n is the number of extra laps fast has made)

Since fast’s speed is twice that of slow: 2(a + b) = a + b + n·L → a + b = n·L → a = n·L - b = (n-1)·L + (L - b) = (n-1)·L + c

a = c + (n-1)·L — This means that the distance of a steps from the head of the linked list to the cycle entry equals the distance of c steps from the meeting point to the cycle entry (possibly with a few extra laps).

Therefore, if we let slow start from the head and fast start from the meeting point, and both advance at the same speed, they will definitely meet at the cycle entry.

Code Implementation#

C
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct ListNode {
int val;
struct ListNode *next;
} ListNode;
/* Check whether a cycle exists */
bool hasCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return true; // Fast and slow pointers meet, so a cycle exists
}
return false; // fast reaches the end, so there is no cycle
}
/* Find the entry node of the cycle */
ListNode* detectCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
// Phase 1: Determine whether a cycle exists
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
// Phase 2: Find the entry point of the cycle
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow; // The meeting point again is the cycle entry
}
}
return NULL; // No cycle
}
C++
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(nullptr) {}
};
class Solution {
public:
// Check whether a cycle exists
bool hasCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) return true;
}
return false;
}
// Find the entry node of the cycle
ListNode* detectCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
// Phase 1: Determine whether a cycle exists
while (fast && fast->next) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
// Phase 2: Find the entry point of the cycle
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return nullptr;
}
};
JavaScript
class ListNode {
constructor(val) {
this.val = val;
this.next = null;
}
}
// Check whether a cycle exists
function hasCycle(head) {
let slow = head;
let fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) return true;
}
return false;
}
// Find the entry node of the cycle
function detectCycle(head) {
let slow = head;
let fast = head;
// Phase 1: Determine whether a cycle exists
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) {
// Phase 2: Find the entry point of the cycle
slow = head;
while (slow !== fast) {
slow = slow.next;
fast = fast.next;
}
return slow;
}
}
return null;
}

Illustrated Process#

Phase 1: Cycle Detection#

Linked list: 3 → 2 → 0 → -4
↑__________↓
Step 1: slow=3, fast=3
Step 2: slow=2, fast=0
Step 3: slow=0, fast=2 ← fast has gone all the way around and lapped slow
Step 4: slow=-4, fast=-4 ← they meet at node -4! There is a cycle!

Phase 2: Find the Cycle Entry#

After the first meeting:
slow resets to the head (3)
fast stays at the meeting point (-4)
Advance at the same speed:
Step 1: slow=2, fast=2
↓ ↓
The two meet at node 2 → node 2 is the entrance to the cycle!

Complexity Analysis#

DimensionAnalysis
Time ComplexityO(n) — slow walks at most n steps (from head to entry and then to the meeting point), each phase is O(n)
Space ComplexityO(1) — only two pointers are used

Key Takeaways#

  1. The core of Floyd’s cycle detection is the speed difference: As long as fast is faster than slow (not necessarily 2x), and the speed difference is coprime with the cycle length, the cycle can be detected. Choosing 2x is the engineering-optimal practice.

  2. The mathematical proof is an interview highlight: Being able to derive a = c + (n-1)·L is the key to distinguishing “memorizing templates” from “truly understanding.”

  3. The elegance of the equal-speed return search: In the second phase, slow and fast walk at the same speed, and their meeting point is the entry — this is the most beautiful part of Floyd’s algorithm.

Extended Thinking#

  • If you need to calculate the length of the cycle, how would you do it? (After meeting, keep fast stationary, and let slow continue walking one full lap while counting)
  • Can the fast pointer move 3 steps at a time? What impact would that have?

Related Articles:

Detecting a Cycle in a Singly Linked List and Finding Its Start: Floyd's Cycle Detection Algorithm
https://www.hehonglei.com/technology/linked-list-cycle/
Author
HHLBlog
Published at
2026-08-10
License
CC BY-NC-SA 4.0