Two Pointers

Two indices squeeze inward so every pair never gets checked.

Brute force
O(n²) — check every pair
With the pattern
O(n) — each pointer moves at most n times (plus O(n log n) if you must sort)
Extra space
O(1)

In plain English

“Two friends start at opposite ends of a bookshelf sorted by thickness, looking for two books that together fill a gap exactly. If the pair is too thick, the friend on the thick end steps inward; too thin, the friend on the thin end steps inward. They meet in the middle having looked at each book only once.”

Why it's fast

Brute force tries all n² pairs. On a sorted array, one comparison tells you which side is wrong: if nums[l] + nums[r] is too big, every pair using r with anything right of l is also too big, so r can be thrown away for good. Each step discards a whole row or column of the pair grid, so you finish in O(n).

Spot it when the problem says…

  • sorted array
  • find a pair (or triplet) that sums to target
  • in-place, O(1) extra space
  • palindrome / compare from both ends
  • remove duplicates or move elements in place
  • maximize area between two lines

Visualize

Two Sum II — sorted input

Find two numbers in a sorted array that add up to the target. Return their indices.

0
1
↑L
1
3
2
4
3
6
4
8
5
11
6
14
7
17
↑R
01/07

Start with the smallest (L) and largest (R) values. Target = 17.

pythonline 2
1def two_sum_sorted(nums, target):2    left, right = 0, len(nums) - 13    while left < right:4        total = nums[left] + nums[right]5        if total == target:6            return [left, right]7        if total < target:8            left += 1      # need a bigger sum9        else:10            right -= 1     # need a smaller sum11    return []

variables

left
0
right
7
target
17

How to apply it

  1. 01Make sure the input is sorted (sort it if order doesn't matter to the answer).
  2. 02Place l = 0 and r = n - 1 (or two pointers moving the same direction for in-place rewrites).
  3. 03Compute something from nums[l] and nums[r] and compare it to the goal.
  4. 04Move exactly the pointer whose side can't possibly be part of a better answer.
  5. 05Stop when the pointers cross; for k-sum, fix one element and run two pointers on the rest.

Variations you'll meet

Opposite ends (Two Sum II)

Classic converging pointers on a sorted array — what the visualizer animates.

python
def two_sum(numbers: list[int], target: int) -> list[int]:    l, r = 0, len(numbers) - 1    while l < r:        s = numbers[l] + numbers[r]        if s == target:            return [l + 1, r + 1]        if s < target:            l += 1      # need bigger sum        else:            r -= 1      # need smaller sum    return []

3Sum (fix one + two pointers)

Sort, loop i, then run the converging pair on i+1..n-1. Skip duplicate values to avoid repeated triplets.

python
def three_sum(nums: list[int]) -> list[list[int]]:    nums.sort()    res = []    for i in range(len(nums) - 2):        if i and nums[i] == nums[i - 1]:            continue        l, r = i + 1, len(nums) - 1        while l < r:            s = nums[i] + nums[l] + nums[r]            if s < 0:                l += 1            elif s > 0:                r -= 1            else:                res.append([nums[i], nums[l], nums[r]])                l += 1                while l < r and nums[l] == nums[l - 1]:                    l += 1    return res

Same direction (read/write pointers)

A slow write pointer and a fast read pointer compact an array in place (Move Zeroes, Remove Duplicates).

Greedy shrink (Container With Most Water)

Not sorted, but you always move the shorter wall because the taller one can never help it.

Common mistakes

  • Using l <= r and pairing an element with itself.
  • Applying it to an unsorted array where moving a pointer gives no information.
  • In 3Sum, forgetting to skip duplicates for both i and l, producing repeated triplets.
  • Moving both pointers after a match when only one should move (or vice versa) and missing answers.
  • Returning 0-based indices when the problem asks for 1-based (Two Sum II).

Practice ladder

Easy → hard. Tick them off as you go.

0/8 solved
  1. 02Move Zeroes ↗Easy
  2. 053Sum ↗Medium
  3. 07Sort Colors ↗Medium

Think you've got it?

Let the AI interviewer throw a Two Pointers problem at you and grade how you explain it.

Mock interview