3Sum: Sorting Plus Two Pointers, With Duplicate Handling
"3Sum" shows up again and again in Meta, Amazon, Google phone screens. It is a Medium problem on paper, but the real test is whether you recognize the Two Pointers pattern quickly and code it cleanly. Part 7 of 12 in the Two Pointers arc.
The Problem
Given an integer array nums, return all unique triplets that sum to zero. The solution set must not contain duplicate triplets — and the deduplication, not the search, is where candidates lose this question.
Input: nums = [-1, 0, 1, 2, -1, -4]
Output: [[-1, -1, 2], [-1, 0, 1]]
Recognizing the Two Pointers Pattern
Two pointers means walking a sequence with two indices that move based on a comparison — from both ends inward, or slow-and-fast in one direction. It turns brute-force pair scans that cost O(n²) into a single O(n) pass, and it is usually the intended answer whenever the input is sorted or can be sorted cheaply.
A k-sum problem reduces to (k−1)-sum with an outer loop: fix one number, then find pairs summing to its negation. After sorting, that inner pair-search is exactly the sorted Two Sum from the start of this arc.
The Approach
Sort. For each anchor index i (skipping repeated anchor values), run converging pointers on the suffix looking for -nums[i]. On a hit, record the triplet, then advance both pointers past any repeated values to avoid duplicate output.
Two pruning wins worth saying: a positive anchor ends the search (everything after is larger), and duplicate anchors are skipped with one comparison against the previous value.
Python Solution
def three_sum(nums: list[int]) -> list[list[int]]:
"""All unique triplets summing to zero."""
nums.sort()
n = len(nums)
result = []
for i in range(n - 2):
if nums[i] > 0:
break # sorted: no zero-sum possible
if i > 0 and nums[i] == nums[i - 1]:
continue # duplicate anchor
left, right = i + 1, n - 1
target = -nums[i]
while left < right:
s = nums[left] + nums[right]
if s == target:
result.append([nums[i], nums[left], nums[right]])
left += 1
right -= 1
while left < right and nums[left] == nums[left - 1]:
left += 1
while left < right and nums[right] == nums[right + 1]:
right -= 1
elif s < target:
left += 1
else:
right -= 1
return result
Complexity
- Time: O(n²) — n anchors, each with a linear pointer sweep; the sort is dominated
- Space: O(1) — in-place sort and pointers, excluding the output list
Interview Tips and Follow-Ups
- A set of sorted tuples also dedupes — mention it, then explain why pointer-skipping avoids the extra hashing and allocation.
- Be ready for 4Sum: one more outer loop, same inner machinery. State the general k-sum recursion.
- Interviewers often ask why sorting is acceptable here (O(n log n) is under the O(n²) total) — have that ready.
That wraps part 7 of the Two Pointers arc. The full Technical Interview category maps all one hundred questions to the nine patterns that dominate FAANG screens — work through an arc end to end and the next unseen variant will feel familiar.
Keep reading
Backspace String Compare Backwards in Constant Space
Compare typed strings with backspaces in O(1) space, scanning backwards. Python solution and complexity analysis for the two pointers interview pattern.
Container With Most Water and the Greedy Pointer Proof
Maximize trapped area and prove the greedy pointer move is safe. Python solution and complexity analysis for the two pointers interview pattern.
Move Zeroes: In Place Partitioning With a Write Pointer
Push all zeroes to the back in one pass, preserving order. Python solution and complexity analysis for the two pointers interview pattern.
Newsletter
New posts, straight to your inbox
One email per post. No spam, no tracking pixels, unsubscribe anytime.
Comments
- No comments yet. Be the first.