Original Problem Statement:
Given an array S of n integers, are there elements a, b, C in S 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.
For example, given array S = [-1, 0, 1, 2, -1, -4],
A solution set is: [[-1, 0, 1], [-1, -1, 2]]
I solved the Two Sum problem on LeetCode some time back and I thought of using it to solve the three sum as well. My idea is that for every element find two elements in the remaining list which sum up to element * -1 to get 0. However, this code doesn't pass all the test, for example
Input: [-4,-2,-2,-2,0,1,2,2,2,3,3,4,4,6,6]
Output: [[-4,-2,6],[-4,0,4],[-4,1,3],[-4,2,2]]
Expected: [[-4,-2,6],[-4,0,4],[-4,1,3],[-4,2,2],[-2,-2,4],[-2,0,2]]
I don't really know what's wrong. Can someone be kind enough to explain the problem to me.
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
def twoSum(self, nums, target):
targ = target
for index, i in enumerate(nums):
targ -= i
if targ in nums[index+1:]:
return [nums[index], nums[nums[index+1:].index(targ)+index+1]]
else:
targ = target
return None
res = []
for index, i in enumerate(nums):
target = i * -1
num = nums[:index] + nums [index+1:]
ans = twoSum(self, num, target)
if ans != None:
temp = ans + [i]
temp.sort()
res.append(temp)
print(res)
import itertools
res.sort()
res = list(res for res,_ in itertools.groupby(res))
return res
Original Question: https://leetcode.com/problems/3sum/description/
The one I'm using to solve this: https://leetcode.com/problems/two-sum/description/
One solution to this problem is to just add all triplets to the hashset, thus eliminating all the duplicates. But there is a simpler solution: sort the array and on every loop skip all values equal to value that has already been processed in the previous iteration.
Create three nested loop first loop runs from start to end (loop counter i), second loop runs from i+1 to end (loop counter j) and third loop runs from j+1 to end (loop counter k) The counter of these loops represents the index of 3 elements of the triplets. Find the sum of ith, jth and kth element.
What are triplets in an array? The triplet of an array is a tuple of three elements of different indices, represented by (i, j, k).
using itertools
.
import itertools
stuff = [-1, 0, 1, 2, -1, -4]
stuff.sort()
ls = []
for subset in itertools.combinations(stuff, 3):
if sum(list(subset))==0:
# first I have sorted the list because of grouping
# Ex: [-1, 0, 1] and [0, 1, -1] are build with the same element
# so here is avoiding this.
if list(subset) not in ls:
ls.append(list(subset))
print(ls)
input/output
input : [-1, 0, 1, 2, -1, -4]
output : [[-1, -1, 2], [-1, 0, 1]]
input : [-4,-2,-2,-2,0,1,2,2,2,3,3,4,4,6,6]
output: [[-4, -2, 6], [-4, 0, 4], [-4, 1, 3], [-4, 2, 2], [-2, -2, 4], [-2, 0, 2]]
Here's another way of solving it which has O(n^2) time complexity and passes the LeetCode test. It counts the occurrences and then sorts (number, count)
tuples so [-1, 0, 1, 2, -1, -4]
becomes [(-4, 1), (-1, 2), (0, 1), (1, 1), (2, 1)]
. Then it iterates from beginning picking first trying to pick each number twice and third greater if possible and add this to result. Then it picks number once and tries to find two greater numbers which sum to 0.
from collections import Counter
class Solution(object):
def threeSum(self, nums):
res = []
counts = Counter(nums)
num_counts = sorted(counts.items())
# Handle the only case where we pick three same nums
if counts[0] >= 3:
res.append([0] * 3)
for i, (first, first_count) in enumerate(num_counts):
# Pick two of these and one greater
if first_count >= 2 and first < 0 and -(first * 2) in counts:
res.append([first, first, -(first * 2)])
# Pick one and two greater
for j in range(i + 1, len(num_counts)):
second, second_count = num_counts[j]
# Pick two of these as second and third num
if second_count >= 2 and -first == 2 * second:
res.append([first, second, second])
# Pick this as second num and third which is greater
third = -(first + second)
if third > second and third in counts:
res.append([first, second, third])
return res
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With