Two Pointers
Beginner · 20 min read · Problem-Solving Patterns, Arrays & Strings
Two indexes moving toward each other or in the same direction to avoid nested loops.
Picture finding two numbers in a sorted array that add up to a target. The brute force tries every pair — O(n²). But the array is sorted, and that's information the brute force ignores. Two pointers use it: one at each end, moving inward, each step ruling out a whole row of pairs at once. One pass, no extra memory.
Two pointers come in two flavours, and recognising which one you need is half the battle.
Flavour 1: opposite ends, moving inward
The grid under the array lists every pair with its sum (row = left value, column = right value). Brute force would check all of them. Each two-pointer step checks one cell and rules out a whole row or column, and you can see exactly which ones and why.
Flavour 2: same direction — read and write
One pointer (read) scans every element; the other (write) marks where the next "kept" element goes. Everything before write is the finished result.
Worked problems — opposite ends
O(n) time, O(1) space — the advantage over the hash-map version when the input is sorted.
Worked problems — read and write
Swapping (instead of copying and filling zeros later) does it in one pass.
Which flavour?
Practice ladder
Interview questions
- Why is it safe to move the left pointer when the sum is too small in a sorted array?
- Two Sum: hash map or two pointers?
Further reading
Key takeaways
- Opposite ends: on sorted data, each comparison discards one element for good → O(n), O(1) space.
- Read & write: read scans, write marks where kept elements go → in-place filtering and partitioning.
- 3Sum = sort + fix one element + two pointers, with careful duplicate skipping.
- For area/water problems, move the pointer at the limiting (shorter) side.
- Use left < right for pairs; don't advance mid after swapping with high.