我正在解决一个问题,我需要找到所有正整数的总和,这些正整数不能写成两个数字的总和。
丰富的数字:数字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 问题。
答案 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()