Let's say we have got a set
{a_1, a_2, a_3, ..., a_n}
The goal is to find a sum that we create in the following way: We find all subsets whose length is 3, then multiply each subset's elements (for the subset {b_1, b_2, b_3}
the result will be b_1*b_2*b_3
). At the end we sum up all these products.
I am looking for a shortest time-execution algorithm.
Example
SET: {3, 2, 1, 2}
Let S be our sum.
S = 3*2*1 + 3*2*2 + 2*1*2 + 3*1*2 = 28
Here is an O(n^2)
approach:
sum = SUM(list)
answer = 0
for each i from 0 to n:
sum -= list[i]
remains = sum
for each j from i+1 to n:
remains -= list[j]
answer += list[i] * list[j] * (remains)
It works because for each two elements x,y
you need to sum x*y*z
(for all elements z
), but the sum of all possible z
values is SUM(list) - x - y
.
So, instead of doing: x*y*z1 + x*y*z2 + ... + x*y*z(n-2)
, you basically do x*y*(z1 + ... + z(n-2))
EDIT: Editted multi-counting due to not multiplying only in the 'tail', as mentioned by @AbhishekBansal . You need to multiply each element only with the 'tail' of the list, where the tail is all the elements after the last element among x,y
.
It is easier to calculate sum of multiplied triplets when repetitions are allowed (like a_1*a_1*a_1). This sum is just (sum^3)
.
Since repetitions are not allowed, we could just subtract them: (sum^3 - 3*sumsquares*sum)
.
But the above formula subtracts elements on main diagonal 3 times while it should be subtracted only once. Need to compensate this: (sum^3 - 3*sumsquares*sum + 2*sumcubes)
.
The above formula does not take into account 3! permutations of each triplet. So it should be divided by 3!
.
Finally we have a linear-time algorithm:
result = (sum^3 - 3*sumsquares*sum + 2*sumcubes)/6
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With