Two hands closing in

Two Pointers

The analogy

You have a sorted row of numbers and want a pair adding to a target. Put one finger at each end. Too big? Move the right finger left. Too small? Move the left finger right. Every move eliminates a whole set of pairs you never have to check, so one sweep does the work of a nested loop.

Visualizer

Two fingers closing in

step 1 / 5
LO
1
0
2
1
3
2
4
3
5
4
7
5
8
6
HI
9
7

Sorted array, looking for two values summing to 10. The naive way is a nested loop — O(n²).target 10

def two_sum_sorted(a, target):
    lo, hi = 0, len(a) - 1
    while lo < hi:
        s = a[lo] + a[hi]
        if s == target:
            return lo, hi
        if s < target:
            lo += 1        # only way to increase
        else:
            hi -= 1        # only way to decrease
    return None

def has_cycle(head):          # Floyd: same pattern
    slow = fast = head
    while fast and fast.next:
        slow, fast = slow.next, fast.next.next
        if slow is fast:
            return True
    return False
Check yourself

Why is moving one pointer safe — why can you discard those pairs?