Time: , space:
.
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
triplets = set()
for i, first in enumerate(nums[0:n-2]):
for j, second in enumerate(nums[i+1:n-1], start=i+1):
for third in nums[j+1:]:
if first+second+third == 0:
triplets.add( tuple(sorted([first, second, third])) )
return list(triplets)
Sorting helps in two ways:
- We can skip duplicate first and second elements which ensures distinct third.
- For a given first element, we can now find the second and third elements in one scan.
Time: , space: sorting’s worst-case,
.
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
nums.sort()
triplets = []
for i, first in enumerate(nums):
# Use distinct first element
if i > 0 and nums[i-1] == nums[i]:
continue
j, k = i+1, len(nums)-1
while j < k:
# Use distinct second element
if j > i+1 and nums[j-1] == nums[j]:
j += 1
continue
triplet_sum = first + nums[j] + nums[k]
if triplet_sum == 0:
triplets.append([ first, nums[j], nums[k] ])
j += 1
k -= 1
continue
# Try increasing the sum
if triplet_sum < 0:
j += 1
else: # Try decreasing the sum
k -= 1
return triplets
Instead of sorting, we could use one set to de-duplicate first elements and a second set to to find the (second, third) pair in a single scan.
Time: , space:
.
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
n = len(nums)
triplets = set()
dup_first = set()
for i, first in enumerate(nums):
if first in dup_first:
continue
dup_first.add(first)
target = -first
seen = set()
for second in nums[i+1:]:
if (third := target-second) in seen:
triplets.add( tuple( sorted( [first, second, third] ) ) )
seen.add(second)
return list(triplets)
Leave a comment