🎓 A1Learner
🔍
0 of 47 lessons completed

Fast and Slow Pointers

Fast and slow pointers are two markers on a list that start apart and then move together. The gap between them turns a distance question into a single walk.

Recognition signal

A problem fits this pattern when it asks for a node a fixed distance from the end. Counting the length first would take an extra pass, and one pass is enough.

signals = [
    "Find a node a fixed distance from the end.",
    "One pass over the list is enough.",
    "The list length is not counted first."
]
for line in signals:
    print(line)

Template: gap then walk together

The template moves the fast marker K steps ahead, then walks both markers together. Two markers with a fixed gap is the pattern in plain words.

class Node:
    def __init__(self, value, nxt=None):
        self.value = value
        self.nxt = nxt

def build(values):
    head = None
    tail = None
    for value in values:
        node = Node(value)
        if head is None:
            head = node
        else:
            tail.nxt = node
        tail = node
    return head

def kth_from_end(head, k):
    fast = head
    for _ in range(k):
        fast = fast.nxt
    slow = head
    while fast is not None:
        slow = slow.nxt
        fast = fast.nxt
    return slow.value

print(kth_from_end(build([10, 20, 30, 40, 50]), 2))

Worked problem: first node as answer

When K equals the length of the list, the fast marker runs out at once. The slow marker never moves, so the first node is the answer.

class Node:
    def __init__(self, value, nxt=None):
        self.value = value
        self.nxt = nxt

def build(values):
    head = None
    tail = None
    for value in values:
        node = Node(value)
        if head is None:
            head = node
        else:
            tail.nxt = node
        tail = node
    return head

def kth_from_end(head, k):
    fast = head
    for _ in range(k):
        fast = fast.nxt
    slow = head
    while fast is not None:
        slow = slow.nxt
        fast = fast.nxt
    return slow.value

print(kth_from_end(build([5, 15, 25, 35]), 4))

Example

class Node:
    def __init__(self, value, nxt=None):
        self.value = value
        self.nxt = nxt

def build(values):
    head = None
    tail = None
    for value in values:
        node = Node(value)
        if head is None:
            head = node
        else:
            tail.nxt = node
        tail = node
    return head

def kth_from_end(head, k):
    fast = head
    for _ in range(k):
        fast = fast.nxt
    slow = head
    while fast is not None:
        slow = slow.nxt
        fast = fast.nxt
    return slow.value

values = [7, 14, 21, 28, 35, 42]
print(values)
print(kth_from_end(build(values), 3))

Key points

  • Slow pointer: a marker that moves one node at a time.
  • Fast pointer: a marker that moves ahead first to set the gap.
  • Use fast and slow pointers to find a node a fixed distance from the end.
  • Move the fast marker K steps first, then move both markers one step at a time.

The fast marker moves 3 steps first, landing on 28. Both markers then move together until the fast marker runs out. The slow marker lands on 28, which is the 3rd node from the end.

Note

when the fast marker runs out of nodes, the slow marker sits on the answer.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

For the 3rd node from the end, how many steps does the fast marker take first?