简体   繁体   中英

Sum of every element with every other element in a list

I am solving a problem in which I need to find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

Abundant Numbers :A number n is called abundant if the sum of its proper divisors is greater than n . And by mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers.

My approach for this problem is : I have a list of abundant numbers and I am finding the sum of every number with every other number in the list. When I have all the new_numbers (sum of the numbers in the abundant numbers list) I will check the numbers which are not in the list and sum them.

But the part where I have to find sum of every number with others takes O(n^2) time . Is there a way to improve the complexity ?

Here's my code with sample example :

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

Actually this is a project euler question.

This is an O(n^2) problem. A lot of students come away from learning about complexity classes think that that is "bad", but once you convince yourself that there's no way around this being a O(n^2) problem, it's best to just accept it. There are improvements that could be made to your code, but not to your algorithm.

Avoiding index will probably speed up your code, as will making l a set rather than a list.

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

As long as k is ordered, then you can safely break in the inner loop if i+j > 28123. I'm fuzzy on efficiency calculations, but i think that makes it 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)

I believe this one is 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)

Update: As Patrick Haugh pointed out this is a O(n^2) problem and any solution will have to be -at best- O(n^2)

What if you used matrix to create a sum of abundant number pairs? Shouldn't that be faster then embedded for-loops

so for example:

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]]

The code would be something like this (using numpy):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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