3Sum
Problem
Given an integer array
The solution set must not contain duplicate triplets.
nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, j != k, and nums[i] + nums[j] + nums[k] == 0.The solution set must not contain duplicate triplets.
Examples
Example 1
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
Example 2
Input: nums = [0,1,1]
Output: []
No triplets sum to 0.
Example 3
Input: nums = [0,0,0]
Output: [[0,0,0]]
Key Insight
3Sum = Fix one element + Two Sum on the rest
3Sum = sort + fix one element + two-pointer 2Sum. Skip duplicates by comparing with previous values.
How to Approach This Problem
Pattern Recognition: When you see keywords like
3sum two-pointers,
think Two Pointers.
Step-by-Step Reasoning
1
If we fix one element nums[i], what remains?
Answer: A 2Sum problem with target = -nums[i]
nums[i] + nums[j] + nums[k] = 0 means nums[j] + nums[k] = -nums[i]. Two Sum!
2
Sorting helps with (select all):
Answer: Both A and B
Sorting enables two-pointer 2Sum (O(n) each) and makes duplicates adjacent (easy to skip).
3
After processing i=1 where nums[1]=-1: [-4, -1, -1, 0, 1, 2] ↑ Should we process i=2 where nums[2]=-1?
Answer: No, skip because nums[2] == nums[1]
If nums[i] == nums[i-1], we've already found all triplets starting with this value. Skip to avoid duplicates.
4
During two-pointer search, after finding a valid triplet: nums = [..., -1, 0, 0, 1, 1, ...] L ↑ R After finding [..., 0, 1] as part of triplet, we should:
Answer: Move L right, skipping duplicate 0s; move R left, skipping duplicate 1s
After finding a triplet, continue searching but skip over duplicate values to avoid finding the same triplet again.
5
What's the time complexity of 3Sum with this approach?
Answer: O(n²)
Sorting is O(n log n). For each of n elements (outer loop), we do O(n) two-pointer search. Total: O(n²).
Solution
def threeSum(nums: List[int]) -> List[List[int]]:
nums.sort()
result = []
for i in range(len(nums) - 2):
# Skip duplicate first elements
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, len(nums) - 1
target = -nums[i]
while left < right:
current_sum = nums[left] + nums[right]
if current_sum == target:
result.append([nums[i], nums[left], nums[right]])
# Skip duplicates
while left < right and nums[left] == nums[left + 1]:
left += 1
while left < right and nums[right] == nums[right - 1]:
right -= 1
left += 1
right -= 1
elif current_sum < target:
left += 1
else:
right -= 1
return result
Complexity Analysis
| Time | O(n²) |
|---|---|
| Space | O(1) |
Master This Pattern
Build intuition with interactive MCQs. Practice Two Pointers problems in the LeetEye app.
Download LeetEye Free