15. 3Sum
Leetcode Blind 75
22th June 2022 ~ Dion Pinto
Description
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] == 0. Notice that the solution set must not contain duplicate triplets. (Problem)
Explanation
I believe that 3Sum becomes rather messy because of the handling of duplicates. We can see this with the following brute force approach (without handling of duplicates).
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
sol=[]
for i in range(len(nums)-2):
for j in range(i+1,len(nums)-1):
if(i!=j):
for k in range(j+1,len(nums)):
if(j!=k):
if(nums[i]+nums[j]+nums[k]==0):
sol.append([nums[i],nums[j],nums[k]])
return sol
INPUT: [-1,0,1,2,-1,-4]
OUTPUT: [[-1,0,1],[-1,2,-1],[0,1,-1]]
In the above output we can notice [-1,0,1] is repeated twice with the order being different. We can solve the order issue by sorting the input array.
...
def threeSum(self, nums: List[int]) -> List[List[int]]:
sol=[]
nums.sort()
for i in range(len(nums)-2):
...
OUTPUT: [[-1,-1,2],[-1,0,1],[-1,0,1]]
Cool now we atleast get the duplicates in order.Now we can focus on eliminating the duplicates. We can notice that if we just skip the repeating values after sorting we can eliminate the duplicates.
We can use the following code to do so.
...
nums.sort()
sol=[]
for i in range(len(nums)-2):
if(i>0 and nums[i]==nums[i-1]):
continue
for j in range(i+1,len(nums)-1):
...
OUTPUT: [[-1,-1,2],[-1,0,1]]
Now finally, we can move onto a more optimized soluton. As we have seen in (two Sum 2). Utilizing a 2 pointer approach to find the j -> nums[l] and k -> nums[r] values. ending with a another check to ensure no duplicates occur.
...
else:
sol.append([nums[i],nums[l],nums[r]])
l+=1
while((l<r) and nums[l]==nums[l-1]):
l+=1
...
Code (Python)
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
sol=[]
nums.sort()
for i in range(len(nums)):
if(i>0 and nums[i]==nums[i-1]):
continue
l,r=i+1,len(nums)-1
while(l<r):
threesum=nums[i]+nums[l]+nums[r]
if(threesum>0):
r-=1
elif(threesum<0):
l+=1
else:
sol.append([nums[i],nums[l],nums[r]])
l+=1
while((l<r) and nums[l]==nums[l-1]):
l+=1
return sol
Time Complexity => o(n2)
Space Complexity => o(1)