Two Pointers
Imagine you have a row of numbers, and you need to find a pair that adds up to a specific target. The naive way is to use a nested loop: point your left finger at the first number, then use your right finger to point at every other number. Then move your left finger to the second number, and so on. This takes \(O(n^2)\) time.
The Two Pointers technique is a clever way to do this in just one pass — taking \(O(n)\) time — by moving two variables (pointers) through the array at the same time.
← → arrow keys to step · click elements to interact
Two Pointer: Pair Sum
Pattern 1: Opposite Ends (Converging Pointers)
This is the most common two-pointer pattern. You place one pointer at the start (left = 0) and one at the end (right = n - 1) of a sorted array.
Say you want to find two numbers that sum to 10 in the array [1, 2, 3, 4, 6, 8, 9]:
- Look at
left(1) +right(9) = 10. Found it! - If the sum was too small (e.g., target was 12), you move the
leftpointer forward to get a bigger number. - If the sum was too big (e.g., target was 8), you move the
rightpointer backward to get a smaller number.
Because the array is sorted, you always know exactly which pointer to move.
Pattern 2: Slow and Fast (Runner Technique)
In this pattern, both pointers start at the same place, but they move at different speeds. The "fast" pointer might move two steps for every one step the "slow" pointer takes.
This is famously used in linked lists to:
- Find the exact middle: When the fast pointer reaches the end, the slow pointer is perfectly in the middle.
- Detect cycles: If the fast pointer laps the slow pointer and they meet, there's a loop! (See Floyd's cycle detection.)
Pattern 3: Sliding View (Same Direction)
Sometimes both pointers move at the same speed but stay a fixed distance apart (like a sliding window), or they process elements in-place to remove duplicates (like a sliding window). For example, the fast pointer reads values, and the slow pointer writes them only if they are unique.