Skip to content

level 8 · Core techniques

Two Pointers

Two markers moving toward each other turn an O(n²) search into O(n).

9 min 75 XP

what is it

Start here

The two-pointer technique is a way of thinking, not a data structure. Instead of one index crawling through a list, you use two — often starting at opposite ends and moving toward each other. On a sorted array, that turns problems that look like they need a nested loop into a single clean pass.

The classic example: find two values that add up to a target. The brute-force way tries every pair — O(n²). With two pointers, you look at the smallest and largest values. Too small a sum? The only way to grow it is to move the left pointer up. Too big? Move the right pointer down. Every move rules out a value for good.

It works because the array is sorted, which gives each comparison meaning: a too-small sum tells you something certain about which pointer to move. Watch the two pointers squeeze inward — they can only ever move toward each other, so the whole thing finishes in one pass.

real-life analogy

Picture it

Two people closing a folding table

One stands at each end and they walk toward the middle. Neither ever backtracks, so between them they cover the whole length exactly once. Two pointers work the same way — each moves only inward, and together they sweep the array a single time.

interactive visualization

Watch it run

The array is sorted for you. Find two values that add up to the target.

  1. 2
    0
  2. 5
    1
  3. 8
    2
  4. 12
    3
  5. 15
    4
  6. 21
    5
  7. 28
    6

Find two values that add up to 20. The array is sorted, which is the key — it lets us start one pointer at each end and squeeze inward.

step 01/9

  • comparing
  • found it
  • ruled out
1function twoSum(a, target) {
2 let lo = 0;
3 let hi = a.length - 1;
4 while (lo < hi) {
5 const sum = a[lo] + a[hi];
6 if (sum === target) return [lo, hi];
7 if (sum < target) lo++;
8 else hi--;
9 }
10 return null;
11}

variables right now

target
20
comparisons 0moves 0

the dry run · every step, in words

9 steps

complexity

What it costs

best case
O(1)
average
O(n)
worst case
O(n)
extra memory
O(1)

One pass, because the two pointers only ever move toward each other — together they take at most n steps. That's down from O(n²) for checking every pair, and it uses no extra memory. The catch: the array must be sorted first.

  • O(1)
  • O(log n)
  • O(n) · this one
  • O(n log n)
  • O(n²)
input size →work →

common mistakes

Common traps

  • Using two pointers on an unsorted array for pair-sum.

    The technique relies on order: 'sum too small → move left up' is only valid because values are sorted. On unsorted data you'd need a different approach (like a hash set).

  • Moving both pointers on every step.

    Move exactly one, chosen by the comparison. Moving both can skip right over the answer.

  • Letting the pointers cross.

    Stop as soon as lo meets or passes hi. Continue past that and you start re-examining pairs you've already ruled out.

quiz

Check yourself

Three questions. Get them all right to finish the lesson.

+75 XP

01Why does the two-pointer pair-sum need a sorted array?

02What does two pointers do to the time complexity of pair-sum?

03On each step, how many pointers do you move?

practice

Solve it on LeetCode

You've seen it run — now write it yourself. These are real LeetCode problems that use exactly this idea, from gentlest to toughest.