Algorithm

3Sum

Two Pointer Pattern

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.

CONSTRAINTS
  • 3 <= nums.length <= 3000
  • Solution set must not contain duplicate triplets
  • -10⁵ <= nums[i] <= 10⁵
EXAMPLE 1
Input: nums = [-1,0,1,2,-1,-4]
Output: [[-1,-1,2],[-1,0,1]]
These are the only two distinct value-triplets that sum to zero; the second -1 in the input does not create a new one.
EXAMPLE 2
Input: nums = [0,0,0]
Output: [[0,0,0]]
0 + 0 + 0 = 0. There is one triplet of values even though it uses three positions.
EXAMPLE 3
Input: nums = [1,2,-2,-1]
Output: []
No three of these values add up to zero, so the answer is empty.
Can the result contain duplicate triplets?
No. Two triplets with the same three values (in any order) count as the same and must appear only once.
Do I return indices or the actual values?
The values. Positions do not appear in the output.
Does the order of triplets, or of numbers inside a triplet, matter?
No — any ordering is accepted.
What if no triplet sums to zero?
Return an empty list.

Finding three numbers that sum to zero is fundamentally about reducing a three-variable search into a simpler, two-variable one. By anchoring one element, we transform the problem into a search for a pair that completes the zero-sum, which is much easier to manage in a sorted environment.

The Exhaustive Search (O(N³))

The most basic way to solve this is to pick every possible triplet (i, j, k) and check if their sum is zero. This involves three nested loops, which is incredibly inefficient. As the number of elements grows, this approach quickly hits a wall and becomes computationally impossible for larger datasets.

python
# Brute force: nested loops
def brute_force(nums):
    res = set()
    for i in range(len(nums)):
        for j in range(i + 1, len(nums)):
            for k in range(j + 1, len(nums)):
                if nums[i] + nums[j] + nums[k] == 0:
                    res.add(tuple(sorted([nums[i], nums[j], nums[k]])))
    return list(res)
Intermediate Approaches: Hash Set (O(N²))

We could fix one anchor nums[i] and then treat the remaining problem as a "Two Sum" search. We could use a hash set to track seen numbers. This is faster than brute force, but hash sets make it surprisingly difficult to handle duplicate triplets in the final output without creating extra sets or sorting the result, which adds significant overhead and complexity to the code.

The Two-Pointer Insight

The true insight here is to use a sorted array. Once the array is sorted, we fix one element as the Anchor, and then use the Two-Pointer Pattern on the rest of the array. The sorted order allows us to not only converge on the answer in O(N) time but also makes it trivially easy to skip duplicates simply by ignoring adjacent numbers that have the same value.

Optimal Strategy: Anchored Convergence

We iterate through the sorted array, using each element as an anchor. For each anchor, we set left and right pointers on the remaining subarray to find pairs that sum to -anchor.
- If the sum is too small, we need a larger value (move left forward).
- If the sum is too large, we need a smaller value (move right backward).
- If we find a match, we store it and move both pointers inward, while skipping any duplicates to maintain uniqueness.

python
# Optimal: anchor + two pointers
def three_sum(nums):
    nums.sort()
    res = []
    for i in range(len(nums) - 2):
        if i > 0 and nums[i] == nums[i-1]: continue
        l, r = i + 1, len(nums) - 1
        while l < r:
            s = nums[i] + nums[l] + nums[r]
            if s == 0:
                res.append([nums[i], nums[l], nums[r]])
                while l < r and nums[l] == nums[l+1]: l += 1
                while l < r and nums[r] == nums[r-1]: r -= 1
                l += 1; r -= 1
            elif s < 0: l += 1
            else: r -= 1
    return res
Worked Example:[-4, -1, -1, 0, 1, 2]
0
-4
1
-1
anchor
2
-1
L
3
0
4
1
5
2
R
We pin our anchor at index 1 (-1), and start Left at 2 and Right at 5. The sum is -1 + -1 + 2 = 0. Match!
0
-4
1
-1
anchor
2
-1
3
0
L
4
1
R
5
2
We record [-1, -1, 2]. Left and Right are advanced past duplicates, landing at 0 (index 3) and 1 (index 4). Sum: -1 + 0 + 1 = 0. Match!
Interactive Strategy Visualization

3Sum Strategy

Fix one, finding pair with Two Pointers

PIVOT
-4
0
L
-1
1
-1
2
0
3
1
4
R
2
5
-4+-1+2=-3
Fix -4. Target: 4. Left: -1, Right: 2. Sum: -3. Too small.
O(N³) Brute Force
O(N²) Time · O(N) Space Hash Set
O(N²) Time · O(1) Space Sort + Converging Scan