From here:
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note:
The solution set must not contain duplicate triplets.
This solution works and is pretty fast but not very memory efficient. I have some comments which I added when writing it to keep track of what I was doing. Specific questions are at bottom.
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
# Early exit conditions
if len(nums) < 3:
return []
results = {}
vals = {}
# Make easy to check if all target values exist
for i, v in enumerate(nums):
if v in vals:
vals[v] += 1
else:
vals[v] = 1
# Go through all matching numbers
# This works because each result is unique
for i, num in enumerate(vals.keys()):
# Modified two sum problem to get -i-j
for j in list(vals.keys())[i:]:
# If checking itself but only is in input once, can't work
if num == j and vals[num] < 2:
continue
target_val = -(num+j)
if target_val in vals:
valid = False
if vals[target_val] > 2:
valid = True
else:
# Check that this isn't either i/j (thus duplicate)
if num != target_val and j != target_val:
valid = True
if valid and tuple(sorted((num, j, target_val))) not in results:
results[tuple(sorted((num, j, target_val)))] = True
return [list(r) for r in results.keys()]
- I dislike the way I'm sorting then converting to a tuple. Is there a better way to do this?
- I feel like I can clean up some of the
if
logic but I'm not totally sure how is best. - I dislike the
list(vals.keys())
approach - is there a better way to do what I'm doing here? I am not a huge fan of it - This one might be out of scope for this Code Review question but this doesn't seem to generalize very well if there were say 4 elements or 8 elements in the target (vs 3). I'd have to continue to add nested lists in order for that to work and the strategy for
if
checking here would get very messy.