Files
leetcode/docs/(algorithms)/02-two-pointers.mdx
T

117 lines
3.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: 'Two Pointers'
description: 'Converging/parallel index walk that prunes the O(n^2) pair space using order.'
---
## The idea
Checking every pair costs O(n²). That is n² boxes to open.
But if the array is **ordered**, you do not need every pair.
Put one pointer at each end. Look at the sum:
- Too small? Only a bigger left value can help. Move left in.
- Too big? Only a smaller right value can help. Move right in.
Each move kills a whole row of the pair space. O(n²) → O(n).
## The picture
```mermaid
flowchart TD
A["2 7 11 15 target 18<br/>L R"] --> B["2 + 15 = 17 < 18<br/>too small → move L right"]
B --> C["2 7 11 15<br/> L R"]
C --> D["7 + 15 = 22 > 18<br/>too big → move R left"]
D --> E["2 7 11 15<br/> L R"]
E --> F["7 + 11 = 18 ✓"]
style F fill:#2e7d32,color:#fff
```
## Not the same as binary search
Binary search **jumps** to the middle and discards half unseen — O(log n).
Two pointers **walks** — every element gets inspected once — O(n).
Both need order. Different moves.
## Two Sum II (LC 167) — the pure template
```python
def two_sum(numbers: list[int], target: int) -> list[int]:
lo, hi = 0, len(numbers) - 1
while lo < hi:
total = numbers[lo] + numbers[hi]
if total == target:
return [lo + 1, hi + 1]
if total < target:
lo += 1 # only a bigger value helps
else:
hi -= 1 # only a smaller value helps
```
## Container With Most Water (LC 11) — move the shorter wall
Water = width × shorter wall.
Moving the taller wall can never help — width shrinks, height cannot grow.
So always move the shorter one. Say this proof in the interview.
```python
def max_area(height: list[int]) -> int:
lo, hi = 0, len(height) - 1
best = 0
while lo < hi:
best = max(best, (hi - lo) * min(height[lo], height[hi]))
if height[lo] < height[hi]:
lo += 1
else:
hi -= 1
return best
```
## 3Sum (LC 15) — fix one, converge two
Sort first. Fix the smallest number. Now it is Two Sum II on the rest.
Skip duplicates at every level or you get repeat triplets.
```python
def three_sum(nums: list[int]) -> list[list[int]]:
nums.sort()
result = []
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue # skip duplicate anchor
lo, hi = i + 1, len(nums) - 1
while lo < hi:
total = nums[i] + nums[lo] + nums[hi]
if total < 0:
lo += 1
elif total > 0:
hi -= 1
else:
result.append([nums[i], nums[lo], nums[hi]])
lo += 1
while lo < hi and nums[lo] == nums[lo - 1]:
lo += 1 # skip duplicate pair
return result
```
## Complexity
| | Time | Space |
|---|---|---|
| Converging pair | O(n) | O(1) |
| 3Sum | O(n²) — sort + n passes | O(1) extra |
## Close-out ritual
Before you submit, say out loud:
1. Time and space complexity.
2. One edge case trace: two elements, all duplicates, or no valid answer.
## Plan problems
**A-set:** LC 125 · 167 · 15 · 11 · 42
**B-set:** LC 392 · 977 · 189 · 80