DocsHub
Linked Lists

Fast & Slow Pointers

Learn the fast and slow pointer technique for detecting cycles, finding midpoints, and more.

Fast & Slow Pointers

The fast and slow pointer technique uses two pointers moving through a linked list at different speeds. The slow pointer moves one step at a time. The fast pointer moves two steps at a time. This simple difference unlocks several powerful algorithms.

Also called Floyd's Cycle Detection Algorithm or the tortoise and hare algorithm.


Problem 1 โ€” detect a cycle

If a linked list has a cycle, the fast pointer will eventually lap the slow pointer and they will meet. If there is no cycle, the fast pointer reaches the end.

Fast & Slow Pointerscycle detection ยท O(n)
๐Ÿข slow (1 step)๐Ÿ‡ fast (2 steps)
1
[0]
2
[1]
3
[2]
4
[3]
5
[4]
6
[5]
cycle: node[5] โ†’ node[3] (value 4)
๐Ÿข slowโ€”
๐Ÿ‡ fastโ€”
fast_slow.py
def has_cycle(head):
slow = fast = head
while fast and fast.next:
slow = slow.next # 1 step
fast = fast.next.next # 2 steps
if slow == fast:
return True # cycle!
return False # no cycle
Call has_cycle(head) โ€” detect if a cycle exists
step 0/14
0%
def has_cycle(head):
    slow = head
    fast = head

    while fast and fast.next:
        slow = slow.next         # move 1 step
        fast = fast.next.next    # move 2 steps

        if slow == fast:
            return True   # they met โ€” cycle exists

    return False   # fast reached end โ€” no cycle

Why they always meet inside the cycle: Once both pointers are inside the cycle, fast gains 1 step on slow every iteration. If the cycle has length L, fast catches slow within L iterations.


Problem 2 โ€” find the midpoint

When fast reaches the end, slow is exactly at the middle.

def find_middle(head):
    slow = head
    fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

    return slow   # slow is at the middle


# Example: 1 โ†’ 2 โ†’ 3 โ†’ 4 โ†’ 5
# After loop: slow = node(3) โ€” the middle

# Even length: 1 โ†’ 2 โ†’ 3 โ†’ 4
# After loop: slow = node(3) โ€” second middle (standard choice)

This is used in merge sort on linked lists โ€” find the middle, split in two, sort each half, merge.


Problem 3 โ€” find the start of a cycle

If a cycle exists, find exactly where it begins.

def find_cycle_start(head):
    slow = head
    fast = head
    meeting_point = None

    # phase 1 โ€” detect cycle
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            meeting_point = slow
            break

    if not meeting_point:
        return None   # no cycle

    # phase 2 โ€” find cycle start
    # move one pointer to head, keep other at meeting point
    # both move at same speed โ€” they meet at cycle start
    pointer1 = head
    pointer2 = meeting_point

    while pointer1 != pointer2:
        pointer1 = pointer1.next
        pointer2 = pointer2.next

    return pointer1   # cycle start

Why this works: The math shows that the distance from head to cycle start equals the distance from the meeting point to cycle start โ€” moving both at equal speed, they meet exactly at the start.


Problem 4 โ€” check if linked list is a palindrome

def is_palindrome(head):
    # step 1 โ€” find middle
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

    # step 2 โ€” reverse the second half
    prev = None
    while slow:
        next_node = slow.next
        slow.next = prev
        prev = slow
        slow = next_node

    # step 3 โ€” compare both halves
    left = head
    right = prev

    while right:
        if left.value != right.value:
            return False
        left = left.next
        right = right.next

    return True

Problem 5 โ€” find kth node from the end

Move fast pointer k steps ahead first, then move both at the same speed. When fast reaches the end, slow is at the kth node from the end.

def kth_from_end(head, k):
    slow = head
    fast = head

    # move fast k steps ahead
    for _ in range(k):
        if not fast:
            return None   # k is larger than list length
        fast = fast.next

    # move both until fast reaches end
    while fast:
        slow = slow.next
        fast = fast.next

    return slow   # kth node from end

All five problems โ€” same two pointers, different questions

ProblemFast speedSlow speedKey insight
Detect cycle2 steps1 stepThey meet if cycle exists
Find midpoint2 steps1 stepWhen fast ends, slow is middle
Find cycle start2 steps then 11 step then 1Math: distances are equal
Palindrome check2 steps1 stepFind middle then compare
Kth from end1 step (offset k)1 stepOffset gap equals k

The fast and slow pointer pattern is one of the most powerful linked list techniques. Recognize it whenever a problem involves cycles, midpoints, or relative positions within a linked list.


Complexity

ProblemTimeSpace
Detect cycleO(n)O(1)
Find midpointO(n)O(1)
Find cycle startO(n)O(1)
Palindrome checkO(n)O(1)
Kth from endO(n)O(1)

On this page