Skip to content
mlmentorship

Linked List Cycle

Check whether a linked list contains a cycle.

Published · 7 min read ·Core ·Intermediate

30-second answer map

Visual first · depth when needed

With a cycle, a pointer moving two links per round gains one cycle position on a pointer moving one link, so they must meet.

Preparing the visual…

ML breadth · active recall

Practice before you read

8 minutes. Explain the mechanism, why it works, when it fails, and one alternative.

How practice works

ML breadth · closed-book attempt

Linked List Cycle

Explain the mechanism, why it works, when it fails, and one alternative.

08:00recommended time

Closing or reloading clears the scratchpad. Only score, weak rubric dimensions, attempt count, and retry date can be stored locally.

Check whether a linked list contains a cycle.

Start with the concrete trace below. It shows the state the algorithm must carry as it runs.

Problem trace

Linked List Cycle: With a cycle, a pointer moving two links per round gains one cycle position on a pointer moving one link, so they must meet.

Input and goalCheck whether a linked list contains a cycle.
Initialize both pointers at headFor 1->2->3->4 with 4.next = 2, set slow = fast = node 1. The loop guard passes because fast and fast.next both exist.
Linked-list topologyNodes, next pointers, and moving algorithm pointers.next4.next -> 2slowfast1234
slowAt1fastAt1guardfast=1 and fast.next=2

Recognize it
Use it for cycle detection in a deterministic next-pointer structure when constant extra space is required and storing every visited node would be unnecessary.
Keep true
After r loop iterations, slow has followed r next links and fast has followed 2r. If no cycle exists fast reaches null; inside a cycle their relative offset changes by one per round.
Reuse it
Different traversal speeds convert a hidden cycle into an inevitable identity collision; guard every fast hop. The technique transfers to repeated-state sequences and cycle-entry algorithms.
Read it this way: For 1->2->3->4 with 4.next = 2, set slow = fast = node 1. The loop guard passes because fast and fast.next both exist. Step through the frames to watch the state change. The last frame shows the answer or the stopping condition.

Pattern: Slow and fast pointers.

Simple idea: One pointer moves one step and the other moves two. Inside a cycle, the fast pointer must catch the slow pointer. Without a cycle, the fast pointer reaches the end.

def has_cycle(head: ListNode | None) -> bool:
   slow = head
   fast = head

   while fast and fast.next:
      slow = slow.next
      fast = fast.next.next
      if slow is fast:
         return True
   return False

Cost: time and space.

The platform supplies ListNode with val and next; this snippet assumes that definition.