繁体   English   中英

查找整数列表中添加到数字的所有数字

[英]Find all numbers in a integer list that add up to a number

我在接受采访时被问到了这个问题。 鉴于以下列表:

[1,2,5,7,3,10,13]

找到最多相加的数字5。

我的解决方案如下:

#sort the list:
l.sort()
result = ()
for i in range(len(l)):
    for j in range(i, len(l)):
         if l[i] + l[j] > 5:
             break
         elif l[i] + l[j] == 5:
             result += (l[i], l[j])

我提出的想法是对列表进行排序,然后循环并查看总和是否大于5.如果是,那么我可以停止循环。 我觉得面试官对这个答案不满意。 有人可以建议一个更好的一个供我将来参考吗?

这将返回总和为5的输入的powerset的所有元素:

>>> input = [1,2,5,7,3,10,13]
>>> import itertools
>>> def powerset(l):
...     return itertools.chain.from_iterable((itertools.combinations(l, i) for i in range(len(l)+1)))
...
>>> filter(lambda v: sum(v) == 5, powerset(input))
[(5,), (2, 3)]

我就是这样做的:

from itertools import permutations
from random import randint


base_list = [randint(-10, 10) for x in range(20)]

def five_sum(base_list, combinations):
    has_negatives = any([base for base in base_list if base < 0])
    if not has_negatives:
        filtered_list = [base for base in base_list if base <= 5]
    else:
        filtered_list = base_list
    perms = list(permutations(filtered_list, combinations))
    filtered_perms = [perm for perm in perms if sum(perm) == 5]
    print(filtered_perms)
    for perm in set(filtered_perms):
        yield perm

print(base_list)
print(list(five_sum(base_list, 2)))

在一个我拥有无限内存的理想世界中,我会用perms = [list(permutations(filtered_list, i)) for i in range(len(filtered_list) + 1)]替换combinations参数, perms = [list(permutations(filtered_list, i)) for i in range(len(filtered_list) + 1)]

另一种使用词典的解决方案

from collections import Counter

l = [1,2,2,5,7,3,10,0,-5]
counter = Counter(l)
keys = counter.keys()
result = []
key = keys.pop()

while True:
  if 5-key in counter:
    result.append((key, 5-key))
    counter[key]-=1
    if counter[key]<=0:
      del counter[key]
      if len(keys) == 0:
        break
      key = keys.pop()
    counter[5-key]-=1
    if counter[5-key]<=0:
      del counter[5-key]
  else:
    del counter[key]        
    if len(keys) == 0:
      break
    key = keys.pop()

print(result)

你得到

[(-5, 10), (5, 0), (3, 2)]

使用len(l)==1000 timeit for proposal solutions:

from timeit import Timer

t = Timer(jose)
print t.timeit(number=1)
#0.00108003616333
t = Timer(dan)
print t.timeit(number=1)
#hangout
t = Timer(morgan)
print t.timeit(number=1)
#0.000875949859619 <--- best time
t = Timer(steven)
print t.timeit(number=1)
#0.0118129253387
t = Timer(sam) #OP
print t.timeit(number=1)
#0.0160880088806

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM