โจ Problem Description
Given an integer array nums, return all the unique triplets [nums[i], nums[j], nums[k]] such that i โ j โ k, and nums[i] + nums[j] + nums[k] == 0.
๐ Constraints:
Solution set must not contain duplicate triplets.
The answer should be a list of triplets, not index-based.
Input array can have both positive and negative numbers.
๐งฉ Core Idea
Although this problem sounds like a straightforward extension of the classic Two Sum, it introduces new challenges:
Need to find all combinations, not just one.
Must eliminate duplicates.
Return triplets of values, not indices.
This changes the optimal strategy from hash-based lookup to a sort + two-pointer approach.
๐งช Why Not Use HashMap like Two Sum?
In Two Sum:
Only one valid pair is needed.
Index-based lookup is prioritized.
No duplicates or ordering constraints.
In 3Sum:
Need all unique value triplets.
Sorting makes it easier to skip duplicates.
Two-pointer technique becomes efficient after sorting.
So in short:
โ Two Sum โ HashMap is optimal
โ Three Sum โ Sorting + Two Pointers is optimal
โ Java Solution: 3Sum with Sorting + Two Pointers
import java.util.*;
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums); // Step 1: sort the array
for (int i = 0; i < nums.length - 2; ++i) {
if (i > 0 && nums[i] == nums[i - 1]) continue; // Skip duplicate a
int target = -nums[i];
int left = i + 1, right = nums.length - 1;
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == target) {
res.add(Arrays.asList(nums[i], nums[left], nums[right]));
// Skip duplicates
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
return res;
}
}
๐ Related Concept: Two Sum with Unique Pairs (Extended Insight)
What if Two Sum also needed:
All pairs (not just one)?
No duplicates?
Only value-based results?
Then it would require sorting + two pointers, just like 3Sum.
class Solution {
public List<List<Integer>> twoSumUniquePairs(int[] nums, int target) {
List<List<Integer>> res = new ArrayList<>();
Arrays.sort(nums);
int left = 0, right = nums.length - 1;
while (left < right) {
int sum = nums[left] + nums[right];
if (sum == target) {
res.add(Arrays.asList(nums[left], nums[right]));
while (left < right && nums[left] == nums[left + 1]) left++;
while (left < right && nums[right] == nums[right - 1]) right--;
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
return res;
}
}