Pattern #02
Two Pointers
EssentialSorted 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.
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: 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");
}
- 1#11 Container With Most WaterGuidemedium
- 2#15 3SumGuidemedium
- 3#16 3Sum ClosestGuidemedium
- 4#18 4SumGuidemedium
- 5#42 Trapping Rain WaterGuidehard
- 6#167 Two Sum II. Input Array Is SortedGuidemedium