I solved this problem by following a straightforward but not optimal algorithm. I sorted the vector in descending order and after that substracted numbers from max to min to see if I get a + b + c = d. Notice that I haven't used anywhere the fact that elements are natural, distinct and 10 000 at most. I suppose these details are the key. Does anyone here have a hint over an optimal way of solving this?
Thank you in advance!
Later Edit: My idea goes like this:
'<<quicksort in descending order>>'
for i:=0 to count { // after sorting, loop through the array
int d := v[i];
for j:=i+1 to count {
int dif1 := d - v[j];
int a := v[j];
for k:=j+1 to count {
if (v[k] > dif1)
continue;
int dif2 := dif1 - v[k];
b := v[k];
for l:=k+1 to count {
if (dif2 = v[l]) {
c := dif2;
return {a, b, c, d}
}
}
}
}
}
What do you think?(sorry for the bad indentation)
Solution in O(n2 log n):
Compute sets of all possible sums and differences:
{ai+aj: 1 <= i,j <= n}
{ai-aj: 1 <= i,j <= n}
(store them in a balanced binary search tree) and check if they have a common element. If yes, there are i,j,k,l such that ai + aj = ak - al, that is ai+aj+al=ak.
Solution in O(an log an), where an is the largest number in the vector:
Compute the polynomial
(xa1+xa2 + ... + xan)3
you can do it in O(an log an) using Fast Fourier Transform (first compute square, then third power; see here for description). Observe that after multiplication a coefficient xbi was formed from multiplication xai * xaj * xak= xai+aj+ak for some i,j,k. Check if there is a power xal in the resulting polynomial.
Unfortunately this allows some i,j,k to be used twice. Subtracting 3(x2a1+...+x2an)*(xa1+...+xan) - 2(x3a1+...+x3an) will remove those xai+aj+ak.
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