2017-09-06 142 views
3

原問題聲明:三和算法解決方案

給定一個n個整數的數組S,是否存在S中的元素a,b,c使得a + b + c = 0?查找數組中所有唯一的三元組,它們的總和爲零。

注意:解決方案集不能包含重複的三元組。

For example, given array S = [-1, 0, 1, 2, -1, -4], 

A solution set is: [[-1, 0, 1], [-1, -1, 2]] 

你好,我解決了上本文給出了兩個和問題一段時間回來,我想用它來解決這三個總和爲好。我的想法是,每個元素找到剩餘列表* -1到0取得該款項高達元素然而兩個元素,此代碼不通過所有測試,例如

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]] 

我不真的知道什麼是錯的。有人能夠友好地向我解釋問題。 謝謝

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 

原題:https://leetcode.com/problems/3sum/description/

的一個我用來解決這個問題:https://leetcode.com/problems/two-sum/description/

+0

請在問題中包含問題的描述,而不是其他網站的鏈接。如果該網站發生故障或更改網址格式,您的問題將來就不會被理解。 – Phrogz

+0

@Phrogz注意到和更改,感謝您的輸入 – someRandomGuy

+0

我發現問題是迭代錯過了可能發生在同一元素兩次的任何組合。我會盡力找出解決辦法並在此發佈答案。 – someRandomGuy

回答

3

使用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 : [-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]] 
+0

完美,我想到了幾種方法來做到這一點。不過,我想通過使用兩個sum方法來做到這一點。您的方法適用於所提供的測試用例,雖然我在LeetCode上爲此輸入提交時間限制超出了時間限制 [-7,-10,-1,3,0,-7,-9,-1,10, 8,-6,4,14,-8,9-,-15,0,-4,-5,9,11,3,-5,-8,2,-6,-14,7,-14, 10,5,-6,7,11,4,-7,11,11,7,7,-4,-14,-12,-13,-14,4,-13,1,-15, - 2,-12,11,-14,-2,10,3,-1,11,-5,1,-2,7,2,-10,-5,-8,-10,14,10, 13,-2,-9,6,-7,-7,7,12,-5,-14,4,0,-11,-8,2,-6,-13,12,0,5, -15,8,-12,-1,-4,-15,2,-5,-9,-7,12,11,6,10,-6,14,-12,9,3,-10 ,10,-8,-2,6,-9,7,7,-7,4,-8,5,-4,8,0,3,11,0,-10,-9] – someRandomGuy

+0

Ran out的空間,這不是代碼的問題,但與LeetCode,所以我會接受你的答案。感謝您的解決方案 – someRandomGuy

+0

@someRandomGuy,感謝您的欣賞和快樂編碼+1。 –

2

這裏的解決它的另一種方式,其具有爲O(n^2)時間複雜度,並傳遞本文給出了測試。它計數出現次數,然後對(number, count)元組進行排序,因此[-1, 0, 1, 2, -1, -4]變爲[(-4, 1), (-1, 2), (0, 1), (1, 1), (2, 1)]。然後它從開始挑選開始迭代,如果可能的話,首先嚐試挑選每個數字兩倍和三分之一,然後將其添加到結果中。然後它挑選一次號碼,並嘗試找到總計爲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