Problem Statement
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] is 0.
Notice that the solution set must not contain duplicate triplets.
Examples
- For array [-1, 0, 1, 2, -1, -4] output will be [-1, -1, 2] and [-1, 0, 1]
- For array [0, 1, 1], there are no triplets that have zero sum
- For array [0, 0, 0], the output will be [0, 0, 0]
Solution
Points of Interest
- Brute force method will be to consider all triplets in array and add them to results if not already there. Time complexity will be of .
- Although there is an approach with which we can find a pair of elements in a sorted array with given sum in . Here we will use Two Pointer method.
- We will first sort the array.
- Then we choose one element and find other elements using this approach in sub-array after that element.
- This will have time complexity of .
Algo
As mentioned above we will use a modified version of Two Pointer method to solve the 2 sum problem for each element of the array.
- Initialize results array, that will contain all such triplets.
- Sort array in increasing order.
- Iterate over array to get 1st element at index. Now our problem is to find a pair of values in array whose sum is the negative of nums[i]. For that:
- Initialize start and end as i+1 and n - 1.
- Loop until start is less than end.
- If sum of start and end elements is greater than negative of nums[i], move the end pointer.
- If sum of start and end elements is less than negative of nums[i], move the start pointer.
- Else, insert the triplet into the results and keep moving the start pointer such that its value is different than initial start value.
- Here you will have all the eligible triplets from nums arrays in results array.
Code
def threeSum(nums: list[int]) -> list[list[int]]:
results = list()
nums.sort()
for i, val in enumerate(nums):
if i > 0 and val == nums[i-1]:
continue
start, end = i + 1, len(nums) - 1
while start < end:
s = nums[start] + nums[end]
if s > -val:
end -= 1
elif s < -val:
start += 1
else:
results.append([val, nums[start], nums[end]])
start += 1
while start < len(nums) and nums[start] == nums[start - 1]:
start += 1
return results
Complexity
- Sorting of array takes time
- And finding a pair for first element at index takes (N - i) time. This adds up as
- Sorting is done in place and we only use few variables, size of which is not dependent on the size of array.