List Every Unique Triplet That Sums to Zero
Solve this Problemnums, find every combination of three different elements whose values add up to zero, and report them with no duplicate triplet appearing twice — a triplet is a duplicate of another if it has the same three values, regardless of which indices produced them.
Since the answer is checked as a single flat list of numbers rather than a grouped structure, package your result this way: sort the three values inside each triplet from smallest to largest, then arrange the triplets themselves from smallest to largest (comparing their first value, then second, then third), and concatenate everything into one array. For example, triplets (2, -1, -1) and (0, -1, 1) would be reported together as [-1, -1, 2, -1, 0, 1].
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
3 ≤ nums.length ≤ 3000 - ◆
-10⁵ ≤ nums[i] ≤ 10⁵
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public int[] zeroSumTriplets(int[] nums) { |
| 3 | Arrays.sort(nums); |
| 4 | List<Integer> result = new ArrayList<>(); |
| 5 | int n = nums.length; |
| 6 | for (int i = 0; i < n - 2; i++) { |
| 7 | if (i > 0 && nums[i] == nums[i - 1]) continue; |
| 8 | int left = i + 1, right = n - 1; |
| 9 | while (left < right) { |
| 10 | int sum = nums[i] + nums[left] + nums[right]; |
| 11 | if (sum == 0) { |
| 12 | result.add(nums[i]); |
| 13 | result.add(nums[left]); |
| 14 | result.add(nums[right]); |
| 15 | left++; |
| 16 | right--; |
| 17 | while (left < right && nums[left] == nums[left - 1]) left++; |
| 18 | while (left < right && nums[right] == nums[right + 1]) right--; |
| 19 | } else if (sum < 0) { |
| 20 | left++; |
| 21 | } else { |
| 22 | right--; |
| 23 | } |
| 24 | } |
| 25 | } |
| 26 | int[] flat = new int[result.size()]; |
| 27 | for (int k = 0; k < flat.length; k++) flat[k] = result.get(k); |
| 28 | return flat; |
| 29 | } |
| 30 | } |
| 31 |
Sort nums first. Original [-1, 0, 1, 2, -1, -4] becomes [-4, -1, -1, 0, 1, 2] — now equal values sit next to each other, which is what makes duplicate-skipping and the two-pointer sweep possible.
Approach & Solutions
Brute Force — Three Nested Loops
BruteCheck every combination of three distinct indices with three nested loops. Whenever a combination sums to zero, sort those three values and use a string key to make sure the same triplet (by value, not index) isn't recorded twice. At the end, sort the collected triplets into the required order and flatten them into one array.
O(n³)O(n) for the dedupe set1class Solution {
2 public int[] zeroSumTriplets(int[] nums) {
3 int n = nums.length;
4 Set<String> seen = new HashSet<>();
5 List<int[]> triplets = new ArrayList<>();
6 for (int i = 0; i < n; i++) {
7 for (int j = i + 1; j < n; j++) {
8 for (int k = j + 1; k < n; k++) {
9 if (nums[i] + nums[j] + nums[k] == 0) {
10 int[] t = {nums[i], nums[j], nums[k]};
11 Arrays.sort(t);
12 String key = t[0] + "," + t[1] + "," + t[2];
13 if (seen.add(key)) triplets.add(t);
14 }
15 }
16 }
17 }
18 triplets.sort((a, b) -> a[0] != b[0] ? a[0] - b[0] : (a[1] != b[1] ? a[1] - b[1] : a[2] - b[2]));
19 int[] flat = new int[triplets.size() * 3];
20 int idx = 0;
21 for (int[] t : triplets) {
22 flat[idx++] = t[0];
23 flat[idx++] = t[1];
24 flat[idx++] = t[2];
25 }
26 return flat;
27 }
28}Optimal — Sort + Two Pointer
OptimalSort the array first. Walk a single pointer i across it to fix the first number of each triplet (skipping over repeats of the previous i so the same first value isn't tried twice). For the remaining slice, use two pointers — left just after i, right at the end — and slide them toward each other: if the three values sum to zero, record the triplet and step both pointers inward past any duplicate values; if the sum is too small, move left up; if it's too large, move right down. Sorting turns the search for the other two numbers into a single O(n) sweep instead of a nested loop.
O(n²)O(1) extra (excluding the sort and output)1class Solution {
2 public int[] zeroSumTriplets(int[] nums) {
3 Arrays.sort(nums);
4 List<Integer> result = new ArrayList<>();
5 int n = nums.length;
6 for (int i = 0; i < n - 2; i++) {
7 if (i > 0 && nums[i] == nums[i - 1]) continue;
8 int left = i + 1, right = n - 1;
9 while (left < right) {
10 int sum = nums[i] + nums[left] + nums[right];
11 if (sum == 0) {
12 result.add(nums[i]);
13 result.add(nums[left]);
14 result.add(nums[right]);
15 left++;
16 right--;
17 while (left < right && nums[left] == nums[left - 1]) left++;
18 while (left < right && nums[right] == nums[right + 1]) right--;
19 } else if (sum < 0) {
20 left++;
21 } else {
22 right--;
23 }
24 }
25 }
26 int[] flat = new int[result.size()];
27 for (int k = 0; k < flat.length; k++) flat[k] = result.get(k);
28 return flat;
29 }
30}