1

a little stuck finding an efficient algorithm for the following problem. The algo has to decide if there are 3 elements a,b and c in an array so that a+b+c is equal to a given number z.

The naive way would be to try out the combinations, of course, but asymptotically the time needed would be too large.

For finding a and b in an array so that the sum is z is much easier. Sort the given array in ascending order and check for every element if z-a exists. But I'm not sure how I'd implement it in the 3 element problem and what time would be needed.

Any help is much appreciated!

Edit: a,b,c and z are integers.

Raighley
  • 57
  • 6

2 Answers2

0

I suppose I should've written a short comment as an answer, but I don't have enough reputation for it ... So here goes nothing!


The best algorithm I can come up with right now is O(n^2), to explain this algorithm better we shall start with the a+b = z in O(n) case (or O(nlgn) if it wasn't sorted)

First of all, iterate {a}, and find {b} such that a+b = z. Naively if you iterate all b this would cost O(n) per {a}, leading to a O(n^2) solution. However, if you iterate {a} increasingly, the value of {b} must be strictly decreasing. We can make use of this information to reduce the time complexity as in this code:

for a = first element, b = last element; a != last; a = next a
while ( ( b != first element ) and (a + b > z) )
      b = previous elemnet of b
if a + b == z
      return true

Note that {b} only goes through the whole list once throughout loop, so it has a complexity of amortized O(n).


Now we can apply this principle back to the original problem, we could iterate through {a}, and apply this O(n) algorithm to {b, c} to find {z-a}, the total complexity is O(n*n = n^2).

Hopefully there is a solution with a lower complexity, I don't think O(n^2) is impressive but I just can't come up with a better one.

haleyk
  • 87
  • 7
0

The approach is very similar to finding a and b with sum z.

First sort the array. And then fix a at position i and check if you have sumz-a in the limits i + 1 to n

Since you have a O(n) algorithm to check if a sum z exist with a and b. We only extend it to fix a and check if two other variable can be used to produce the sum. Giving a overall run time of O(n^2)

From here

// returns true if there is triplet with sum equal
// to 'sum' present in A[]. Also, prints the triplet
bool find3Numbers(int A[], int arr_size, int sum)
{
    int l, r;

    /* Sort the elements */
    sort(A, A+arr_size);

    /* Now fix the first element one by one and find the
       other two elements */
    for (int i=0; i<arr_size-2; i++)
    {

        // To find the other two elements, start two index
        // variables from two corners of the array and move
        // them toward each other
        l = i + 1; // index of the first element in the
                   // remaining elements
        r = arr_size-1; // index of the last element
        while (l < r)
        {
            if( A[i] + A[l] + A[r] == sum)
            {
                printf("Triplet is %d, %d, %d", A[i], 
                                         A[l], A[r]);
                return true;
            }
            else if (A[i] + A[l] + A[r] < sum)
                l++;
            else // A[i] + A[l] + A[r] > sum
                r--;
        }
    }

    // If we reach here, then no triplet was found
    return false;
}
thebenman
  • 1,517
  • 13
  • 26