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
iflogic 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
ifchecking here would get very messy.