每个元素与列表中每个其他元素的总和

时间:2016-10-25 13:39:40

标签: python algorithm

我正在解决一个问题,我需要找到所有正整数的总和,这些正整数不能写成两个数字的总和。

  

丰富的数字:数字n被称为丰富的,如果它的总和   适当的除数大于n。通过数学分析,它   可以显示大于28123的所有整数都可以写成   两个数字的总和。

我解决这个问题的方法是: 我有一个包含大量数字的列表,我在列表中找到每个数字与其他所有数字的总和。当我拥有所有new_numbers(丰富数字列表中的数字之和)时,我将检查列表中没有的数字并将它们相加。

但是,我必须找到每个数字的总和的部分花费O(n ^ 2)时间。有没有办法提高复杂性?

这是我的代码示例:

k=[1,2,3]    # actual list with 7427 numbers 
l=[]
for i in k:
    for j in k[k.index(i):]:
        if i+j<28123 and i+j not in l:
            l.append(i+j)
print l,len(l)

# result -->[2, 3, 4, 5, 6] 5

实际上这是一个project euler 问题。

4 个答案:

答案 0 :(得分:1)

这是一个O(n ^ 2)问题。许多学生离开了解复杂性课程认为这是“坏”,但一旦你说服自己没有办法解决这个问题,那么最好接受它。可以对您的代码进行改进,但不对您的算法进行改进。

避免index可能会加快您的代码速度,同时使l成为一个集合而不是列表。

k = abundant_list
s = set()
for i, x in enumerate(k): #i is index of x
    for j in k[i:]:
        l = x+j #no reason to do addition twice
        if l<28123:
            s.add(l) #sets discard duplicates automatically

答案 1 :(得分:0)

只要k被命令,那么如果i + j&gt;你可以安全地打破内循环。我对效率计算模糊不清,但我认为这就是O(nlogn)。

k=[1,2,3]    # actual list with 7427 numbers 
l=[]
for i in k:
    for j in k[k.index(i):]:
        n = i+j
        if n<28123:
            if n not in l:
                l.append(i+j)
        else:
           break # this will save you the time of adding numbers you know are > 28123
print l,len(l)

答案 2 :(得分:0)

我相信这个是O(n * log(n))

MAGIC_NUMBER = 28123
k = abundant_numbers
l = [True] * MAGIC_NUMBER
final = []

for i in range(len(k)):
    for j in range(i, len(k)):
        if i + j > MAGIC_NUMBER:
            break
        l[i+j] = False

for index, value in enumerate(l):
    if value:
        final.append(index)

更新:正如Patrick Haugh所指出的那样,这是一个O(n ^ 2)问题,任何解决方案都必须是-at best-O(n ^ 2)

答案 3 :(得分:0)

如果您使用矩阵创建大量数字对的总和怎么办?不应该比嵌入式for循环更快

所以例如:

ka = [[12 18 20]
      [12 18 20]
      [12 18 20]]

ka'= [[12 12 12]
      [18 18 18]
      [20 20 20]]

sum= [[24 30 32]
      [30 36 38]
      [32 38 40]]

代码将是这样的(使用numpy):

k=[12, 18, 20] 
ka = np.tile(np.array(k),(len(k),1))
sums = ka + ka.transpose()