我有一个清单:
l = [1,3,4,6,7,8,9,11,13,...]
和数字n。
如何有效地检查数字n
是否可以表示为列表l
中两个数字(允许重复)的总和。
如果数字在列表中,则除非可以表示为两个数字,否则它不会计数(例如,对于l = [2,3,4] 3将不计算,但是4将会计算。
令人尴尬的是,这是我尝试过的:
def is_sum_of_2num_inlist(n, num_list):
num_list = filter(lambda x: x < n, num_list)
for num1 in num_list:
for num2 in num_list:
if num1+num2 == n:
return True
return False
由于
答案 0 :(得分:3)
def summable(n, l):
for v in l:
l_no_v = l[:]
l_no_v.remove(v)
if n - v in l_no_v:
return True
return False
编辑:解释......
itertools.cominations
是获得所有可能答案的好方法,但它比这个版本慢了4倍,因为这是一个循环,一旦获得可能的解决方案就会失败。
这会循环l
中的值,复制l
删除v
,以便我们不会将v
添加到自身(即如果没有误报,则n = 4; l = [2, 1]
)。然后从v
中减去n
,如果该值在l
中,则有两个数字总计为n
。如果您想要返回这些数字,而不是只返回True
{。}}。
答案 1 :(得分:2)
虽然你可以通过两次运行列表来检查这一点,但我建议将列表转换为一组性能,因为x in set()
会在线性时间内进行搜索。
由于n
可以是相同数字的总和,所以您只需遍历该集合一次,并检查集合中其他位置是否发生n - i
。
以下内容应该有效。
>>> def is_sum_of_numbers(n, numbers):
... for i in numbers:
... if n - i in numbers:
... return True
... return False
...
>>>
>>>
>>> numbers = {2,7,8,9}
>>> is_sum_of_numbers(9, numbers) # 2 + 7
True
>>> is_sum_of_numbers(5, numbers)
False
>>> is_sum_of_numbers(18, numbers) # 9 + 9
True
答案 2 :(得分:0)
如果我得到了OP的关注 -
正如问题所说repeats are allowed within the list l
这个过程我认为虽然有点慢但是好。所以如果你需要计算出现的情况以及条件的存在,那么请回答这个问题,但如果你想要一个bolean esixtence与其他人一起检查仅仅是性能问题。
您可以使用itertools.combinations。它将为您提供所有组合,而不是排列。现在你可以使用sum函数得到总和。
from itertools import combinations
l = [1,3,4,6,7,8,9,11,13]
checks = [4,6] #these are the numbers to check
for chk in checks:
for sm in combinations(l,2):
if chk == sum(sm): #sum(sm) means sum(1,3) for the first pass of the loop
#Do something
答案 3 :(得分:0)
如果列表 已订购,您可以使用两个变量来浏览列表,一个从列表的开头开始,一个在结尾,如果总和如果总和小于N,则两个变量中的变量大于N,如果总和小于N,则在列表的开头分配给变量。如果总和为N,则您找到了这两个值。当两个变量相遇时,你可以停止。
如果列表未订购,则从列表的开头开始,并使用变量x
浏览列表。您需要其他结构,如hashset或其他结构。在每个步骤中,如果值N-x
在那里,您将在第二个哈希集中查找。如果有,您已经找到了两个加起来为N的数字。如果您没有在哈希集中添加N-x
并分配给x
以下内容值。我建议使用hashset,因为查找和插入操作都是O(1)。
两种算法都是线性
抱歉,我无法直接在python中编写代码,因为我不能使用它。
正如我在评论HERE中所说的那样,您的问题已经解决了