簡體   English   中英

兩個人找到所有可能獨特的夫妻

[英]twoSum to find all the possible unique couples

我有這樣的問題

給定n個整數的數組nums ,是否有元素abnumsa + b = 10? 找出陣列中所有唯一的夫妻,它們給出了目標的總和。

注意:

解決方案集不得包含重復的一對。

例:

 Given nums = [4, 7, 6, 3, 5], target = 10 because 4+ 6= 7+ 3 = 10 return [[4, 6], [7,3]] 

我的解決方案

class SolutionAll: #Single Pass Approach 
    def twoSum(self, nums, target) -> List[List[int]]:
        """
        :type nums: List[int]
        :type target: int
        """
        nums.sort()
        nums_d:dict = {}
        couples = []

        if len(nums) < 2:
            return []

        for i in range(len(nums)):
            if i > 0 and nums[i] == nums[i-1]: continue #skip the duplicates

            complement = target - nums[i]

            if nums_d.get(complement) != None:
                couples.append([nums[i], complement])          
            nums_d[nums[i]] = i                            
        return couples 

TestCase結果:

target: 9 
nums: [4, 7, 6, 3, 5]
DEBUG complement: 6
DEBUG nums_d: {3: 0}
DEBUG couples: []
DEBUG complement: 5
DEBUG nums_d: {3: 0, 4: 1}
DEBUG couples: []
DEBUG complement: 4
DEBUG nums_d: {3: 0, 4: 1, 5: 2}
DEBUG couples: [[5, 4]]
DEBUG complement: 3
DEBUG nums_d: {3: 0, 4: 1, 5: 2, 6: 3}
DEBUG couples: [[5, 4], [6, 3]]
DEBUG complement: 2
DEBUG nums_d: {3: 0, 4: 1, 5: 2, 6: 3, 7: 4}
DEBUG couples: [[5, 4], [6, 3]]
result: [[5, 4], [6, 3]]
.
target: 2 
nums: [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
DEBUG complement: 2
DEBUG nums_d: {0: 0}
DEBUG couples: []
DEBUG complement: 1
DEBUG nums_d: {0: 0, 1: 9}
DEBUG couples: []
result: []

該解決方案適用於[4,7,6,3,5],但失敗的是[0,0,0,0,0,0,0,0,0,1,1,1,1,1,1]

我試圖刪除重復項,但得到意想不到的結果。

如何通過這一個Pass解決方案解決問題?

您的代碼的問題是它跳過重復的數字 ,而不是重復的 因為

if i > 0 and nums[i] == nums[i-1]: continue #skip the duplicates

你的代碼永遠不會嘗試總和1 + 1 = 2


這是一個具有O(n)復雜度的工作解決方案:

from collections import Counter

def two_sum(nums, target):
    nums = Counter(nums)  # count how many times each number occurs

    for num in list(nums):  # iterate over a copy because we'll delete elements
        complement = target - num

        if complement not in nums:
            continue

        # if the number is its own complement, check if it
        # occurred at least twice in the input
        if num == complement and nums[num] < 2:
            continue

        yield (num, complement)

        # delete the number from the dict so that we won't
        # output any duplicate pairs
        del nums[num]
>>> list(two_sum([4, 7, 6, 3, 5], 10))
[(4, 6), (7, 3)]
>>> list(two_sum([0, 0, 0, 1, 1, 1], 2))
[(1, 1)]

也可以看看:

不確定你的解決方案有什么問題(並且不確定它的正確性),但你可以通過“漂亮的pythonic”方式輕松實現這一點:

def func(nums,target):
    return [(a,b) for a in nums for b in nums if a+b == target]

它假設只有元素順序不同的兩個元組是唯一的,並且元素可以在同一元組中使用兩次。 如果問題的定義不是這樣,那么您可以從返回的值中過濾掉這些元組。

編輯:見下面的討論。

from itertools import combinations

list(set([(a,b) for a,b in combinations(sorted(nums),2) if a+b == target]))

這也將刪除重復項。

其他版本:

>>> nums = [4, 7, 6, 3, 5]
>>> target = 9 
>>> set((a, target-a) for a in nums if target-a in set(nums))
{(4, 5), (5, 4), (3, 6), (6, 3)}

對於每一個元素anums ,如果target-a中也nums ,我們有:

  • a + target-a = target (明顯);
  • atarget-a都在nums

由於我們遍歷每a ,我們得到所有的解決方案。

要擺脫重復(x, y)(y, x)

>>> set((a, target-a) for a in nums if 2*a<=target and target-a in set(nums))
{(4, 5), (3, 6)}

因為2*a <= target相當於a <= target-a 當滿足a > target-a和所請求的條件時,我們有一個先前的b = target-a因此(b, target-b)是一個解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM