The Problem

Given head, the head of a linked list, determine if the linked list has a cycle in it.

There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter.

Return true if there is a cycle in the linked list. Otherwise, return false.

Interactive Visualization

Speed:
Linked List Visualization
slow (1 step)
fast (2 steps)
meeting point
Code
fun hasCycle(head: ListNode?): Boolean {    var slow = head    var fast = head    while (fast != null && fast.next != null) {        slow = slow?.next        fast = fast.next?.next        if (slow == fast) {            return true        }    }    return false}
Status
Press Step or Play to begin.

How It Works

Key Insight

Floyd's cycle detection uses two pointers moving at different speeds: a slow pointer (tortoise) that moves one step at a time, and a fast pointer (hare) that moves two steps at a time. If there is a cycle, the fast pointer will eventually lap the slow pointer and they will meet inside the cycle. If there is no cycle, the fast pointer will reach the end of the list (null).

The Algorithm

  • Initialize: Both slow and fast start at head
  • Each iteration: Move slow forward 1 node, move fast forward 2 nodes
  • Check loop condition: Continue while fast is not null and fast.next is not null
  • If slow == fast: The pointers have met inside the cycle โ€” return True
  • If loop ends: fast reached the end of the list โ€” no cycle, return False

Complexity

Time O(n)
Space O(1)

If there is no cycle, the fast pointer reaches the end in n/2 steps. If there is a cycle, the fast pointer closes the gap by 1 node per iteration, so they meet within one full loop of the cycle. Only two pointer variables are used โ€” no extra data structures needed.