1
\$\begingroup\$

I have an array. Now I want to find the total of, sum of the subarray multiplied by its last element, for all the possible subarrays. This is what I have right now:

n = int(input())
a = []
for _ in range(n):
 a.append(int(input()))
total = 0
for i in range(1, n+1):
 for j in range(n+1-i):
 temp = a[j:j+i]
 total += sum(temp)*temp[-1]
print(total)

Example Input:

3
1
2
3

Output:

53

Explanation:

1*1 + 2*2 + 3*3 + (1+2)*2 + (2+3)*3 + (1+2+3)*3 = 53

My code works fine, but is quite slow. How can I optimise it?

Graipher
41.6k7 gold badges70 silver badges134 bronze badges
asked Sep 10, 2018 at 19:15
\$\endgroup\$
0

1 Answer 1

4
\$\begingroup\$

First I would suggest to separate I/O from the computation, and define a function to compute the subarray sum. That increases the clarity of the program and allows to add test cases more easily:

def subarray_sum(a):
 """Compute sum of all subarrays of a, multiplied by its last element"""
 n = len(a)
 total = 0
 for i in range(1, n + 1):
 for j in range(n + 1 - i):
 temp = a[j:j + i]
 total += sum(temp) * temp[-1]
 return total

Using sum() with generator expressions this can be shortened to

def subarray_sum(a):
 n = len(a)
 total = sum(sum(sum(a[i:j + 1]) * a[j] for j in range(i, n))
 for i in range(n))
 return total

But the time complexity is still \$ O(n^3) \$ because of the three nested loops.

In order to find a more efficient method, let's compute the sum for a 3-element array \$ [a, b, c] \$ explicitly:

$$ a \cdot a + b \cdot b + c \cdot c \\ + (a+b)\cdot b + (b+c) \cdot c \\ + (a+b+c) \cdot c $$ Rearranging terms, this becomes $$ a \cdot a + (a + 2b) \cdot b + (a + 2b + 3c) \cdot c $$ Can you spot the pattern? This can be computed with a single traversal of the array, i.e. in \$ O(n) \$ time.

answered Sep 10, 2018 at 20:17
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.