Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given a vector of maximum 10 000 natural and distinct numbers, find 4 numbers(a, b, c, d) such that a + b + c = d

Tags:

algorithm

math

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)

like image 421
king_kong Avatar asked Dec 17 '22 00:12

king_kong


1 Answers

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.

like image 132
sdcvvc Avatar answered Feb 16 '23 00:02

sdcvvc