Fix one number at a time and hunt for a pair that cancels it out — which turns three unknowns into a Two Sum II problem run once per fixed value.
Given an array, find every unique triplet that sums to zero. Checking every triple directly costs , and even before that, "every unique triplet" hides a second problem: the same values can be found more than once unless duplicates are handled deliberately.
Sorting first solves both problems at once. It makes the two-pointer sweep valid, and it puts equal values next to each other so they're cheap to skip.
Why fixing one value turns this into Two Sum II
Reduce to a problem you've already solved
- Fixing
nums[i]as the pivot turns "three numbers sum to zero" into "two numbers sum to-nums[i]" — exactly Two Sum II, just with a target that moves as the outer loop advances. - The sorted order that makes the inner two-pointer sweep valid is the same proof as before: the sum tells you which side is hopeless to keep.
- Once
nums[i] > 0, no pivot from here on can reach zero with two non-negative-or-larger partners — the outer loop can stop.
What sorting doesn't solve by itself
- Skipping duplicate values inside the inner sweep only avoids repeating a pair for one fixed pivot — you still need to separately skip a pivot value that repeats the previous one.
- It doesn't bound the output size: in the worst case (many zeros) the result itself has triplets, so the total work can't beat that no matter how the pointers move.
- Sorting discards the original indices — fine here, since the answer only needs values, not positions.
- "triplets" or "three numbers" that sum to a target
- "no duplicate triplets in the result"
- asked for every valid combination, not just one
- values (not original positions) matter in the answer
The pattern
- 1Sort the array.
- 2
For each index
i, skip it if it repeats the previous pivot. - 3
Two-pointer the remainder for target
-nums[i], skipping repeat values onleftandrightafter recording a hit. - 4Stop the outer loop once
nums[i] > 0.
Complexity
An O(n) two-pointer sweep runs once per pivot, dominating the O(n log n) sort.
Auxiliary space only — excludes the sort's internal use and the output list itself.
Common pitfalls
Forgetting to skip duplicate pivots
Not comparing nums[i] to nums[i - 1] reruns the identical
inner sweep for equal pivot values, producing the same triplet
more than once.
Forgetting to skip duplicates after a hit
Advancing left and right by one without first skipping past
equal neighbours re-records the same triplet on the next
iteration.
Starting the inner pointers at the wrong index
left and right must start at i + 1 and n - 1 — starting
left at 0 lets the pivot pair with itself.
Moving the wrong inner pointer
Same inversion risk as Two Sum II, just against a moving target:
move left when the sum is too small, right when it's too big.
Variants worth knowing
- 1
3Sum Closest — track the closest sum seen instead of matching exactly.
- 2
4Sum — fix two pivots instead of one, then two-pointer the rest; the same idea nested a level deeper.
- 3
Valid Triangle Number — fixes the largest value instead of walking forward, and counts a whole range of pairs per step instead of one at a time.

