What is the two pointers pattern?
Two pointers uses two indexes or references to track the most useful pair of positions in a sequence. The pointers may begin at opposite ends, move in the same direction at different speeds, or separate a read position from a write position.
For a sorted pair-sum problem, the pattern works because the order makes movement meaningful. If the smallest-plus-largest sum is too small, pairing that smallest value with anything smaller than the current largest cannot reach the target. The left value is no longer useful, so the left pointer moves right. The symmetric argument moves the right pointer left when the sum is too large.
Before each comparison, every pair outside the current [left, right] range has already been ruled out. The answer, if one remains, is still inside the range.
When should you consider two pointers?
A comparison can tell you which boundary value cannot participate in a valid answer.
The prompt asks for a target sum, a closest combination, or another relationship among positions.
Read and write pointers can remove duplicates or move selected values without a second array.
Different speeds can detect cycles or locate a midpoint in linked structures.
Do not use opposite-end movement merely because a problem contains an array. You need a rule that proves which side can be discarded. Without that proof, moving a pointer can skip the answer.
Step-by-step: pair sum in a sorted array
Given the sorted values [1, 2, 4, 6, 8, 9], find a pair whose sum is 10.
Start with the smallest and largest values.
- Place
leftat 1 andrightat 9. - Compute 1 + 9 = 10.
- The target is found, so return the pair.
For a target of 12, the first sum would be 10, which is too small. Moving the right pointer left would only make the sum smaller. The safe move is left += 1, producing 2 + 9 = 11, then 4 + 9 = 13, then moving right left to test 4 + 8 = 12.
Reusable two pointers outline
left = 0
right = values.length - 1
while left < right:
state = combine(values[left], values[right])
if state is the answer:
return answer
else if state is too small:
left += 1
else:
right -= 1
return no answer
The comparison rule changes by problem, but the reasoning should stay explicit: inspect the current pair, determine which side can no longer help, move that pointer, and guarantee that the interval shrinks.
Why is it O(n)?
The left pointer moves only right and the right pointer moves only left. Across the entire run, the two pointers can move inward at most n - 1 times before meeting. Even though there are two variables, the work is one pass: O(n) time and O(1) extra space.
A brute-force pair check uses nested loops and considers O(n²) pairs. Two pointers avoids revisiting pairs that sorted order has already ruled out.
Common two pointers mistakes
- Ignoring the precondition: opposite-end pair sum usually relies on sorted order.
- Moving the wrong side: say how the sum changes before choosing a pointer.
- Moving both pointers automatically: this can skip a valid answer unless a match justifies it.
- Using
left <= rightwithout thinking: pair problems normally require two distinct positions. - Calling indexes values: the pointers are positions; the current values are
values[left]andvalues[right].
“Because the array is sorted, a sum that is too small proves the current left value cannot form the target with any remaining value. I move left right; the symmetric rule moves right left.”