Skip to content

3Sum

Given an integer array 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. Notice that the solution set must not contain duplicate triplets.

InputOutput
[-1,0,1,2,-1,-4][[-1,-1,2],[-1,0,1]]
[0,1,1][]
[0,0,0][[0,0,0]]
  • 3 <= nums.length <= 3000
  • -10^5 <= nums[i] <= 10^5
ApproachTimeSpaceBest When
Sort + Two PointersO(n²)O(1)*Standard answer — elegant and fast
Hash SetO(n²)O(n)Unfamiliar with two-pointer pattern

* O(log n) or O(n) if sorting space counts.

Recommended
Sort + Two Pointers
O(n²) time · O(1) space
Alternative
Hash Set
O(n²) time · O(n) space
Section titled “Approach 1: Sort + Two Pointers (Recommended)”
★ Recommended

Sort the array. For each index i, use two pointers — left = i+1 and right = n-1 — to find pairs that sum to -nums[i]. Skip duplicate values for i and for the inner pointers after finding a triplet.

⏱ Time O(n²) Fixed outer + two-pointer inner 💾 Space O(1) Sorting in-place

Input: [-1, 0, 1, 2, -1, -4]

Sorted: [-4, -1, -1, 0, 1, 2]

inums[i]leftrightsumaction
0-41→45→5all < 0left advances to right
1-125-1-1+2=0✓ add [-1,-1,2], skip dups
1-134-1+0+1=0✓ add [-1,0,1]
2-1skipdup of i=1, continue
30450+1+2=3>0, right—
30left≥rightdone

Animated walkthrough

Sort + Two Pointers walking through [-1,0,1,2,-1,-4]

Use Next or Autoplay to watch the outer pointer fix one element while inner two pointers converge to find zero-sum triplets.

Step 1 of 5
Waiting to begin...
Array state
Memory / lookup state

function threeSum(nums):
sort(nums)
result = []
for i in range(len(nums) - 2):
if nums[i] > 0: break
if i > 0 and nums[i] == nums[i-1]: continue // skip dup outer
left, right = i + 1, len(nums) - 1
while left < right:
s = nums[i] + nums[left] + nums[right]
if s == 0:
result.append([nums[i], nums[left], nums[right]])
while left < right and nums[left] == nums[left+1]: left++
while left < right and nums[right] == nums[right-1]: right--
left++; right--
elif s < 0:
left++
else:
right--
return result
three_sum_sort_two_pointer.py
from typing import List
def three_sum_sort_two_pointer(nums: List[int]) -> List[List[int]]:
nums.sort()
result = []
n = len(nums)
for i in range(n - 2):
if nums[i] > 0:
break
if i > 0 and nums[i] == nums[i - 1]:
continue
left, right = i + 1, n - 1
while left < right:
s = nums[i] + nums[left] + nums[right]
if s == 0:
result.append([nums[i], nums[left], nums[right]])
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 s < 0:
left += 1
else:
right -= 1
return result
print(three_sum_sort_two_pointer([-1, 0, 1, 2, -1, -4])) # [[-1, -1, 2], [-1, 0, 1]]
print(three_sum_sort_two_pointer([0, 1, 1])) # []
print(three_sum_sort_two_pointer([0, 0, 0])) # [[0, 0, 0]]
✓ Simple

Sort the array. For each index i, scan j from i+1 to n-1 using a set to check whether -(nums[i] + nums[j]) was already seen in the current inner scan. Because the array is sorted and we skip duplicate i values, sorted triplets are naturally deduplicated.

⏱ Time O(n²) Outer × inner scan 💾 Space O(n) Inner set per outer iteration

Input: [-1, 0, 1, 2, -1, -4] (after sorting: [-4, -1, -1, 0, 1, 2])

For i=1, nums[i]=-1:

  • j=2: need = -(-1 + -1) = 2, seen=; 2 not in seen → add -1 to seen
  • j=3: need = -(-1 + 0) = 1, seen=-1; 1 not in seen → add 0 to seen
  • j=4: need = -(-1 + 1) = 0, seen=0; 0 not in seen → add 1 to seen
  • j=5: need = -(-1 + 2) = -1, seen=1; -1 in seen → add [-1,-1,2]

Wait — the triplet is [nums[i], need, nums[j]] = [-1, -1, 2]

Continuing with j=5 already recorded… next i=3, nums[i]=0:

  • j=4: need = -(0+1) = -1, seen=; not in seen → add 1
  • j=5: need = -(0+2) = -2, seen=1; not in seen → add 2

No new triplets at i=3.

function threeSumHashSet(nums):
sort(nums)
result = []
for i in range(len(nums) - 2):
if i > 0 and nums[i] == nums[i-1]: continue
seen = set()
for j in range(i+1, len(nums)):
need = -(nums[i] + nums[j])
if need in seen:
triplet = [nums[i], need, nums[j]]
if triplet not in result:
result.append(triplet)
seen.add(nums[j])
return result
three_sum_hash_set.py
from typing import List
def three_sum_hash_set(nums: List[int]) -> List[List[int]]:
nums.sort()
result = []
n = len(nums)
for i in range(n - 2):
if i > 0 and nums[i] == nums[i - 1]:
continue
seen = set()
j = i + 1
while j < n:
need = -(nums[i] + nums[j])
if need in seen:
triplet = [nums[i], need, nums[j]]
if triplet not in result:
result.append(triplet)
seen.add(nums[j])
j += 1
return result
print(three_sum_hash_set([-1, 0, 1, 2, -1, -4])) # [[-1, -1, 2], [-1, 0, 1]]
print(three_sum_hash_set([0, 1, 1])) # []
print(three_sum_hash_set([0, 0, 0])) # [[0, 0, 0]]
✓ Simple

A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.

⏱ Time O(n) Optimized complexity 💾 Space O(1) Efficient space usage
function approach3():
// Implementation approach goes here
3sum_optimized.py
"""
Solution for 3Sum
"""
def solve():
"""Implementation for approach 3 of 3Sum"""
pass
if __name__ == "__main__":
print("Solution ready")