The two-pointer technique uses two indices into an array, moving them toward each other or in tandem, to solve a problem in that would otherwise require work.
Opposite-direction pointers
Start one pointer at the beginning and one at the end. At each step, compare values and move one (or both) pointers inward. Classic example: in a sorted array, find a pair that sums to a target. Move left forward if the current sum is too small, right backward if too large. time, no extra space.
Same-direction pointers
Both pointers start at the left and move forward at different speeds. Used to partition an array in place (think the partition step in quicksort), to remove duplicates from a sorted array, or to compress runs.
Common problems
- Remove duplicates from a sorted array: slow pointer marks the next write position, fast pointer scans
- Trap rainwater: opposite-end pointers tracking running max heights
- 3Sum: outer loop plus two-pointer pass inside, total
- Move zeros to the end: same-direction, partition in place
When it works
Two pointers shine when the data is sorted (or can be sorted cheaply) and when a smart way to "move" the pointers exists — i.e., advancing one pointer monotonically rules out a whole class of configurations. If you find yourself writing nested loops over an array and the inner loop's range depends on the outer, it's worth asking whether two pointers could collapse them.