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.

Previous: Hash Maps & Sets · Next: Sliding Window