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)/6If 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