Skip to content
ΣDSA Patterns
Menu
Language

Pattern #02

Two Pointers

Essential

Sorted arrays, pair conditions, or coordinated movement from both ends.

When to use

Use on sorted arrays for pair/triple sums, or when you can decide which end to move based on a comparison. also for in-place reverse/partition.

Recognition cues

  • Array is sorted (or can be sorted without losing the answer)
  • Find pair / triple with a target sum
  • Opposite ends, meet in the middle
  • Remove duplicates in-place

Common pitfalls

  • Sorting when original indices are required (store indices first)
  • Infinite loops if you forget to move a pointer after a match
  • Duplicate handling in 3Sum-style problems

90-second recognition drill

Which pattern fits best?

  • Array is sorted (or can be sorted without losing the answer)
  • Find pair / triple with a target sum
  • Opposite ends, meet in the middle

Interactive

Mental model

A full worked walkthrough of the invariant. Pause, scrub the dots, or use ← →. Aim to narrate each step yourself.

Step 1 of 8
1
2
3
4
7
11

L = 0, R = n-1

Sorted array. Find a pair that sums to target 9.

How to think about it

Place left at the start and right at the end (or both at the start for same-direction variants). Each step, compare and move the pointer that can improve the answer. Opposite ends for pair sums; same direction for in-place partitions.

Common variants

Variant Movement Example
Opposite ends left++ / right– by sum vs target Two Sum II
Same direction slow/fast for in-place writes Remove duplicates
Container move the shorter height inward Container With Most Water

Complexity baseline

O(n) after sorting (sort is often O(n log n)). Constant extra space unless you store results.

Template

Same skeleton in TypeScript, Python, and C#. Adapt the invariant; keep the structure.

Two Pointers · Template
/** Two pointers template: sorted two-sum (1-based indices). */
export function twoSumSorted(numbers: number[], target: number): number[] {
  let lo = 0, hi = numbers.length - 1;
  while (lo < hi) {
    const sum = numbers[lo]! + numbers[hi]!;
    if (sum === target) return [lo + 1, hi + 1];
    if (sum < target) lo++;
    else hi--;
  }
  throw new Error("No solution");
}
/** Two pointers template: sorted two-sum (1-based indices). */
export function twoSumSorted(numbers: number[], target: number): number[] {
  let lo = 0, hi = numbers.length - 1;
  while (lo < hi) {
    const sum = numbers[lo]! + numbers[hi]!;
    if (sum === target) return [lo + 1, hi + 1];
    if (sum < target) lo++;
    else hi--;
  }
  throw new Error("No solution");
}
#StatusProblemTypeDone
  1. 1#11 Container With Most WaterGuide
  2. 2#15 3SumGuide
  3. 3#16 3Sum ClosestGuide
  4. 4#18 4SumGuide
  5. 5#42 Trapping Rain WaterGuide
  6. 6#167 Two Sum II. Input Array Is SortedGuide