Two Pointers

Walk pointers toward each other to cut a quadratic search down to one pass.

The idea

Two Pointers is usually the first moment DSA stops feeling like memorization and starts feeling like a trick you own. The idea: instead of checking every pair of elements with two nested loops, you keep two indices and move them with intent โ€” because the structure of the data (usually sortedness) tells you which moves can be safely skipped.

That's the entire pattern. Everything else โ€” fast/slow pointers, converging pointers, partition pointers โ€” is a variation on "my next move is provably safe to make, so I never have to look back."

How to recognize it

  • The input is sorted, or you're allowed to sort it without breaking the problem.
  • You're looking for a pair, triplet, or range that satisfies a condition (sum, difference, containment).
  • The brute force is O(nยฒ) over pairs, and the check for each pair is O(1).
  • The phrase "in-place" appears โ€” partitioning and de-duplication love two pointers.
  • It's a linked list and someone said the word "cycle" or "middle" โ€” that's the fast/slow variant.

When to reach for it

  • Pair-with-target-sum in a sorted array (the canonical case).
  • Comparing from both ends inward: palindromes, container problems, trapping water.
  • Deduplicating or partitioning in place with a read pointer and a write pointer.
  • Merging two sorted sequences without extra passes.

The mental model

Think of the sorted array as a grid of all possible pairs (i, j). Brute force visits all of it. Two pointers starts at one corner โ€” smallest i, largest j โ€” and every comparison eliminates an entire row or column: if the sum is too small, no pair with this i can work (j is already as big as it gets), so i++ discards the row. Too big? j-- discards the column. Each step kills n possibilities, so n steps finish the job.

The pattern generalizes whenever you can prove that same one-directional claim: "given what I just observed, moving this pointer can only help, and it never needs to move back." If you can't make that argument, two pointers is the wrong tool โ€” that's not a failure of technique, it's the pattern telling you the structure isn't there.

O(n) time for the standard converging scan (each pointer moves at most n steps total), O(1) extra space. Add O(n log n) if you had to sort first.

Where people get burned

  • Using it on unsorted data where the "safe to move" argument doesn't hold โ€” the answers will be wrong, not slow.
  • Off-by-one at the crossing: decide up front whether left < right or left <= right is your loop condition and what it means for your problem.
  • In 3Sum-style problems, forgetting to skip duplicate values after a hit โ€” you'll emit the same triplet repeatedly.
  • Moving both pointers on a match without thinking โ€” sometimes only one side may advance safely.

Practice progression

Knowing the pattern is half the job. Showing up daily is the other half.

DSAMotivator tracks this exact progression โ€” with streaks, XP, and a map that fills in as you go.

Start free โ€” 7 days