0% completed
Problem Statement
Given an array of unsorted numbers, find all unique triplets in it that add up to zero.
Example 1:
Input: [-3, 0, 1, 2, -1, 1, -2]
Output: [[-3, 1, 2], [-2, 0, 2], [-2, 1, 1], [-1, 0, 1]]
Explanation: There are four unique triplets whose sum is equal to zero. smallest sum.'
Example 2:
Input: [-5, 2, -1, -2, 3]
Output: [[-5, 2, 3], [-2, -1, 3]]
Explanation: There are two unique triplets whose sum is equal to zero.
Constraints:
3 <= arr.length <= 3000
- -10<sup>5</sup> <= arr[i] <= 10<sup>5</sup>
Solution
This problem follows the Two Pointers pattern and shares similarities with Pair with Target Sum. A couple of differences are that the input array is not sorted and instead of a pair we need to find triplets with a target sum of zero.
To follow a similar approach, first, we will sort the array and then iterate through it taking one number at a time. Let’s say during our iteration we are at number ‘X’, so we need to find ‘Y’ and ‘Z’ such that X + Y + Z == 0. At this stage, our problem translates into finding a pair whose sum is equal to “-X” (as from the above equation Y + Z==−X).
Another difference from Pair with Target Sum
is that we need to find all the unique triplets. To handle this, we have to skip any duplicate number. Since we will be sorting the array, so all the duplicate numbers will be next to each other and are easier to skip.
Step-by-Step Algorithm
-
Sort the Array:
- Sort the input array in non-decreasing order. This helps in easily skipping duplicate elements and applying the two-pointer technique.
-
Iterate through the Array:
- Use a for loop to iterate through the array, stopping at the third-to-last element.
- For each element, check if it's the same as the previous one to avoid duplicates.
- If it's the same, skip to the next iteration.
-
Fix the Current Element and Find Pairs:
- Fix the current element and use two pointers to find pairs whose sum is the negative of the fixed element (
targetSum = -arr[i]
). - The left pointer starts from the next element (
i + 1
) and the right pointer starts from the end of the array.
- Fix the current element and use two pointers to find pairs whose sum is the negative of the fixed element (
-
Find Pairs with Two Pointers:
- Calculate the sum of the left pointer and the right pointer (
currentSum = arr[left] + arr[right]
). - If the
currentSum
equalstargetSum
, add the triplet to the list ([-targetSum, arr[left], arr[right]]
) and move both pointers to the next unique elements. - If
currentSum
is less thantargetSum
, move the left pointer to the right to increase the sum. - If
currentSum
is greater thantargetSum
, move the right pointer to the left to decrease the sum.
- Calculate the sum of the left pointer and the right pointer (
-
Skip Duplicates:
- Ensure that the left and right pointers skip duplicate elements to avoid counting the same triplet multiple times.
-
Return the Result:
- After processing all elements, return the list of unique triplets.
Algorithm Walkthrough
Let's walk through the algorithm with the input [-5, 2, -1, -2, 3]
.
-
Sort the Array:
- Input:
[-5, 2, -1, -2, 3]
- Sorted:
[-5, -2, -1, 2, 3]
- Input:
-
Fix
-5
(index 0),left
pointer at-2
(index 1), andright
pointer at3
(index 4):- Target Sum:
-(-5) = 5
- Sum =
-2 + 3 = 1
(less thantargetSum
), moveleft
to-1
(index 2) - Sum =
-1 + 3 = 2
(less thantargetSum
), moveleft
to2
(index 3) - Sum =
2 + 3 = 5
, found triplet[-5, 2, 3]
- Move
left
to 4 andright
to 3 (end of this iteration)
- Target Sum:
-
Fix
-2
(index 1),left
pointer at-1
(index 2), andright
pointer at3
(index 4):- Target Sum:
-(-2) = 2
- Sum =
-1 + 3 = 2
, found triplet[-2, -1, 3]
- Move
left
to2
andright
to 3
- Target Sum:
-
Fix
-1
(index 2),left
pointer at2
(index 3), andright
pointer at3
(index 4):- Target Sum:
-(-1) = 1
- Sum =
2 + 3 = 5
(greater thantargetSum
), moveright
to2
(end of this iteration)
- Target Sum:
-
End of loop since all elements are processed.
Output: [[ -5, 2, 3], [ -2, -1, 3]]
Let's visualize the example 2 via below diagram.
Code
Here is what our algorithm will look like:
Time Complexity
Sorting the array will take O(N * logN). The searchPair() function will take O(N). As we are calling searchPair() for every number in the input array, this means that overall searchTriplets() will take O(N * logN + N^2), which is asymptotically equivalent to O(N^2).
Space Complexity
Ignoring the space required for the output array, the space complexity of the above algorithm will be O(N) which is required for sorting.