我正在努力为重复的面试问题做准备。给定一个数组,找到对,得到它们的和为k。我在这种情况下使用python字典而不是排序方法。代码如下:
def sumToK(lst):
k = 16 # <- define the k here
d = {} # build a dictionary
# build the hashmap key = val of lst, value = i
for index, val in enumerate(lst):
d[val] = index
# find the key; if a key is in the dict, and not the same index as the current key
for i, val in enumerate(lst):
if (k-val) in d and d[k-val] != i:
print k-val, val
a = [1,4,45,6,10,12,3]
sumToK(a)
我以上述方式获取重复值。我怎么能避免呢?此外,如果数组包含重复值,该怎么办例如a = [1,4,45,6,10,12,4,8,8]谢谢。
答案 0 :(得分:4)
你做得太多了。您根本不需要跟踪索引,您可以一次完成。只保留到目前为止所有数字的set
,对于每个新号码n
,您可以检查其对(k - n
)是否已经在你的集合中:
def find_pairs(numbers, k):
seen = set()
for n in numbers:
if k - n in seen:
print n, k - n
seen.add(n)
a = [1,4,45,6,10,12,3]
find_pairs(a, 16)
# 10 6
# 12 4
如果要防止打印重复对,可以更改条件以确保n not in seen
。
答案 1 :(得分:1)
假设您只想查找值而不是它们在列表/数组中的位置
import itertools as it
l = [1, 2, 3, 2, 3]
k = 4
s=[(a,b) for a,b in it.combinations(l,2) if a+b == k]
产生
[(1, 3), (1, 3), (2, 2)]
如果你想要独特的配对
set(s)
给出
set([(1, 3), (2, 2)])
答案 2 :(得分:0)
您发布的代码中存在缩进错误。注释开始“找到键”之后的for循环需要缩进。
通过“重复值”我收集你的意思是你得到值4,12和值12,4。你可以通过让你的测试要求第一个数小于第二个来消除这个,例如
至于消除重复,请使用集合而不是字典。你的代码看起来过于复杂。
def sumTo(k, lst):
answer =set()
summands = set(lst)
for small in range(k/2):
large = k - small
if small in summands and large in summands:
answer.add((small, large))
return answer
答案 3 :(得分:0)
编辑:将产品更改为组合以避免自我组合
使用一些ol&#39;时尚功能蟒蛇。
from itertools import combination
a = [1,4,45,6,10,12,4,8,8]
k = 16
set(
map(
lambda aa: tuple(sorted(aa)),
filter(
lambda (a1, a2): a1+a2 == k,
combination(a, 2)
)
)
)
[Out]: set([(6, 10), (4, 12), (8, 8)])