Python twoSum找到所有可能的独特夫妇

Python twoSum找到所有可能的独特夫妇,python,python-3.x,algorithm,Python,Python 3.x,Algorithm,我有这样一个问题 给定一个由n个整数组成的数组nums,在nums中是否有元素a、b使得a+b=10?查找数组中所有唯一的对,该数组给出目标的和 注意: Given nums = [4, 7, 6, 3, 5], target = 10 because 4+ 6= 7+ 3 = 10 return [[4, 6], [7,3]] 解决方案集不得包含重复对 示例: Given nums = [4, 7, 6, 3, 5], target = 10 because 4+ 6=

我有这样一个问题

给定一个由n个整数组成的数组
nums
,在
nums
中是否有元素a、b使得a+b=10?查找数组中所有唯一的对,该数组给出目标的和

注意:

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

because   4+ 6= 7+ 3   = 10
return  [[4, 6], [7,3]]

解决方案集不得包含重复对

示例:

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 
该解决方案适用于[4,7,6,3,5],但在[0,0,0,0,0,0,0,0,1,1,1,1]时失败

我试图删除重复项,但得到了意外的结果


如何使用此一次性解决方案解决问题?

不确定您的解决方案有什么问题(也不确定它的正确性),但您可以通过“非常简单”的方式轻松实现这一点:


它假设只有元素顺序不同的两个元组是唯一的,并且一个元素可以在同一个元组中使用两次。如果问题的定义不同,则可以从返回值中筛选出这些元组。

编辑:请参阅下面的讨论

from itertools import combinations

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

这也将删除重复项。

代码的问题在于它跳过重复的数字,而不是重复的对。因为

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]

另见:

其他版本:

>>> 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)}
对于
nums
的每个元素
a
,如果
target-a
也在
nums
中,我们有:

  • a+target-a=target
    (明显)
  • a
    target-a
    都在
    nums
因为我们循环了每个
a
,所以我们得到了所有的解决方案

要清除重复的
(x,y)
(y,x)


设置((a,目标-a)对于NUM中的a,如果2*a有什么作用
,NUM中是否有元素a、b,使得a+b=10
有关?在数组中找到所有唯一的对,它们的和为零
??所有这些
类解决方案是什么:
我在这里看到的东西?谁在教人们垃圾?性能重要吗?或者你愿意吗接受O(n^2),如果它简化了代码?对不起,我更正了它@goodvibration@Aran-Fey
谁在教人们[对象定向编程]?
leetcode,来命名相关的一个。投票支持生成器。由于所有错误的原因快速:)令人惊讶,我尝试了
如果I>1和nums[I]==nums[I-2]:继续#跳过重复的
,它能用。@Alice:
它能用吗?你问题中的代码
nums=(1,0,1)
哦,等等,你在排序。不确定
nums=(4,6,4)
。对。固定的。但是现在丑陋:-)
list(set([(min(a,b),max(a,b))for…])
也缺乏魅力,正如
list(set([(a,b)如果asince组合按输入顺序返回,我们可能会这样:list(set([(a,b)表示a,b)表示组合(排序(nums),2)如果a+b==target])看起来更好,开始时更容易阅读。输入的N个大小,匹配目标的M对数(O(N²)),以及R结果大小:O(NlogN+M+R),而不是O(N+M+R)“M的常数更大”。我猜。
>>> 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)]
>>> 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)}
>>> set((a, target-a) for a in nums if 2*a<=target and target-a in set(nums))
{(4, 5), (3, 6)}