Skip to content
Problem · Canonical Warm-Up
mediumsort · two-pointer · duplicate-skipTime · O(n^2)Space · O(1)

3Sum Triplet Target

Problem statement

Statement

Given an integer array nums, return every triplet [nums[i], nums[j], nums[k]] with distinct indices such that the three values sum to zero. The returned set must contain no duplicate triplets.

Examples

nums = [-1, 0, 1, 2, -1, -4]
-> [[-1, -1, 2], [-1, 0, 1]]
   (-1 appears twice in the input, so [-1, -1, 2] is legal;
    but [-1, 0, 1] must be reported once, not twice)

nums = [0, 1, 1]
-> []

nums = [0, 0, 0]
-> [[0, 0, 0]]

nums = [0, 0, 0, 0]
-> [[0, 0, 0]]       (still once, despite four ways to pick the indices)

Constraints

  • 3 <= len(nums) <= 3000
  • -10^5 <= nums[i] <= 10^5
  • Triplets are compared by their multiset of values, not by index. Order within a triplet does not matter and neither does the order of the output.

What this problem is really testing

Reduction, and then bookkeeping. The reduction is quick: fix one element and the remaining question is "find two values summing to -nums[i]", which is Two Sum. Almost everyone reaches that in a minute. The rest of the interview is spent on duplicate suppression, and that is where the problem is actually decided.

The distinction that trips people is between duplicate indices and duplicate values. The statement forbids reusing an index, which is easy. It also forbids reporting the same multiset twice, which is not, because the input may legitimately contain repeated values and a triplet such as [-1, -1, 2] depends on that repetition being available. So you cannot simply discard repeated values up front; you must allow a value to be used as many times as it appears, while ensuring each distinct triplet surfaces once.

Sorting is what makes both halves tractable at once, and it is worth being explicit about the double payoff, because candidates usually name only one. First, order lets the inner search run with two converging pointers in O(n) instead of a hash pass, which keeps auxiliary space at O(1). Second, order puts equal values next to each other, so "have I already used this value in this position?" becomes "is it the same as my neighbour?", a constant-time test. One O(n log n) investment, two structural wins. Pay it up front and the rest of the algorithm falls out.