Find four elements that sum to a given value | Set 2

Given an array of integers, find any one combination of four elements in the array whose sum is equal to a given value X.

For example,

Input: array = {10, 2, 3, 4, 5, 9, 7, 8} 
       X = 23 
Output: 3 5 7 8
Sum of output is equal to 23, 
i.e. 3 + 5 + 7 + 8 = 23.

Input: array = {1, 2, 3, 4, 5, 9, 7, 8}
       X = 16 
Output: 1 3 5 7
Sum of output is equal to 16, 
i.e. 1 + 3 + 5 + 7 = 16.

We have discussed a O(n^3) algorithm in the previous post on this topic. The problem can be solved in O(n^2Logn) time with the help of auxiliary space.



Thanks to itsnimish for suggesting this method. Following is the detailed process.

Method 1: Two Pointers Algorithm.
Approach: Let the input array be A[].

  1. Create an auxiliary array aux[] and store sum of all possible pairs in aux[]. The size of aux[] will be n*(n-1)/2 where n is the size of A[].
  2. Sort the auxiliary array aux[].
  3. Now the problem reduces to find two elements in aux[] with sum equal to X. We can use method 1 of this post to find the two elements efficiently. There is following important point to note though:
    An element of aux[] represents a pair from A[]. While picking two elements from aux[], we must check whether the two elements have an element of A[] in common. For example, if first element sum of A[1] and A[2], and second element is sum of A[2] and A[4], then these two elements of aux[] don’t represent four distinct elements of input array A[].

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <bits/stdc++.h>
using namespace std;
  
// The following structure is needed
// to store pair sums in aux[]
class pairSum {
public:
    // index (int A[]) of first element in pair
    int first;
  
    // index of second element in pair
    int sec;
  
    // sum of the pair
    int sum;
};
  
// Following function is needed
// for library function qsort()
int compare(const void* a, const void* b)
{
    return (
        (*(pairSum*)a).sum
        - (*(pairSum*)b).sum);
}
  
// Function to check if two given pairs
// have any common element or not
bool noCommon(pairSum a, pairSum b)
{
    if (a.first == b.first
        || a.first == b.sec
        || a.sec == b.first
        || a.sec == b.sec)
        return false;
    return true;
}
  
// The function finds four
// elements with given sum X
void findFourElements(
    int arr[], int n, int X)
{
    int i, j;
  
    // Create an auxiliary array
    // to store all pair sums
    int size = (n * (n - 1)) / 2;
    pairSum aux[size];
  
    /* Generate all possible pairs 
from A[] and store sums 
    of all possible pairs in aux[] */
    int k = 0;
    for (i = 0; i < n - 1; i++) {
        for (j = i + 1; j < n; j++) {
            aux[k].sum = arr[i] + arr[j];
            aux[k].first = i;
            aux[k].sec = j;
            k++;
        }
    }
  
    // Sort the aux[] array using
    // library function for sorting
    qsort(aux, size, sizeof(aux[0]), compare);
  
    // Now start two index variables
    // from two corners of array
    // and move them toward each other.
    i = 0;
    j = size - 1;
    while (i < size && j >= 0) {
        if (
            (aux[i].sum + aux[j].sum == X)
            && noCommon(aux[i], aux[j])) {
            cout << arr[aux[i].first]
                 << ", " << arr[aux[i].sec]
                 << ", " << arr[aux[j].first]
                 << ", " << arr[aux[j].sec]
                 << endl;
            return;
        }
        else if (aux[i].sum + aux[j].sum < X)
            i++;
        else
            j--;
    }
}
  
// Driver code
int main()
{
    int arr[] = { 10, 20, 30, 40, 1, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int X = 91;
    findFourElements(arr, n, X);
    return 0;
}
  
// This is code is contributed by rathbhupendra

chevron_right


C

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <stdio.h>
#include <stdlib.h>
  
// The following structure is
// needed to store pair sums in aux[]
struct pairSum {
  
    // index (int A[]) of first element in pair
    int first;
  
    // index of second element in pair
    int sec;
  
    // sum of the pair
    int sum;
};
  
// Following function is needed
// for library function qsort()
int compare(const void* a, const void* b)
{
    return (
        (*(pairSum*)a).sum
        - (*(pairSum*)b).sum);
}
  
// Function to check if two given
// pairs have any common element or not
bool noCommon(
    struct pairSum a, struct pairSum b)
{
    if (a.first == b.first
        || a.first == b.sec
        || a.sec == b.first
        || a.sec == b.sec)
        return false;
    return true;
}
  
// The function finds four
// elements with given sum X
void findFourElements(
    int arr[], int n, int X)
{
    int i, j;
  
    // Create an auxiliary array
    // to store all pair sums
    int size = (n * (n - 1)) / 2;
    struct pairSum aux[size];
  
    /* Generate all possible pairs 
from A[] and store sums
       of all possible pairs in aux[] */
    int k = 0;
    for (i = 0; i < n - 1; i++) {
        for (j = i + 1; j < n; j++) {
            aux[k].sum = arr[i] + arr[j];
            aux[k].first = i;
            aux[k].sec = j;
            k++;
        }
    }
  
    // Sort the aux[] array using
    // library function for sorting
    qsort(aux, size, sizeof(aux[0]), compare);
  
    // Now start two index variables
    // from two corners of array
    // and move them toward each other.
    i = 0;
    j = size - 1;
    while (i < size && j >= 0) {
        if (
            (aux[i].sum + aux[j].sum == X)
            && noCommon(aux[i], aux[j])) {
            printf("%d, %d, %d, %d\n",
                   arr[aux[i].first],
                   arr[aux[i].sec],
                   arr[aux[j].first],
                   arr[aux[j].sec]);
            return;
        }
        else if (aux[i].sum + aux[j].sum < X)
            i++;
        else
            j--;
    }
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 10, 20, 30, 40, 1, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int X = 91;
    findFourElements(arr, n, X);
    return 0;
}

chevron_right



Output:

20, 1, 30, 40

Please note that the above code prints only one quadruple. If we remove the return statement and add statements “i++; j–;”, then it prints same quadruple five times. The code can modified to print all quadruples only once. It has been kept this way to keep it simple.

Complexity Analysis:

  • Time complexity: O(n^2Logn).
    The step 1 takes O(n^2) time. The second step is sorting an array of size O(n^2). Sorting can be done in O(n^2Logn) time using merge sort or heap sort or any other O(nLogn) algorithm. The third step takes O(n^2) time. So overall complexity is O(n^2Logn).
  • Auxiliary Space: O(n^2).
    The size of the auxiliary array is O(n^2). The big size of the auxiliary array can be a concern in this method.

Method 2: Hashing Based Solution[O(n2)]
Approach:

  1. Store sums of all pairs in a hash table
  2. Traverse through all pairs again and search for X – (current pair sum) in the hash table.
  3. If a pair is found with the required sum, then make sure that all elements are distinct array elements and an element is not considered more than once.

Below image is a dry run of the above approach:

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// A hashing based  CPP program
// to find if there are
// four elements with given sum.
#include <bits/stdc++.h>
using namespace std;
  
// The function finds four
// elements with given sum X
void findFourElements(
    int arr[], int n, int X)
{
    // Store sums of all pairs
    // in a hash table
    unordered_map<int, pair<int, int> > mp;
    for (int i = 0; i < n - 1; i++)
        for (int j = i + 1; j < n; j++)
            mp[arr[i] + arr[j]] = { i, j };
  
    // Traverse through all pairs and search
    // for X - (current pair sum).
    for (int i = 0; i < n - 1; i++) {
        for (int j = i + 1; j < n; j++) {
            int sum = arr[i] + arr[j];
  
            // If X - sum is present in hash table,
            if (mp.find(X - sum) != mp.end()) {
  
                // Making sure that all elements are
                // distinct array elements and an element
                // is not considered more than once.
                pair<int, int> p = mp[X - sum];
                if (p.first != i && p.first != j
                    && p.second != i && p.second != j) {
                    cout << arr[i] << ", "
                         << arr[j] << ", "
                         << arr[p.first] << ", "
                         << arr[p.second];
                    return;
                }
            }
        }
    }
}
  
// Driver program to test above function
int main()
{
    int arr[] = { 10, 20, 30, 40, 1, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int X = 91;
    findFourElements(arr, n, X);
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// A hashing based Java program to find
// if there are four elements with given sum.
import java.util.HashMap;
class GFG {
    static class pair {
        int first, second;
        public pair(int first, int second)
        {
            this.first = first;
            this.second = second;
        }
    }
  
    // The function finds four elements
    // with given sum X
    static void findFourElements(
        int arr[],
        int n, int X)
    {
        // Store sums of all pairs in a hash table
        HashMap<Integer,
                pair>
            mp = new HashMap<Integer,
                             pair>();
        for (int i = 0; i < n - 1; i++)
            for (int j = i + 1; j < n; j++)
                mp.put(arr[i] + arr[j],
                       new pair(i, j));
  
        // Traverse through all pairs and search
        // for X - (current pair sum).
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                int sum = arr[i] + arr[j];
  
                // If X - sum is present in hash table,
                if (mp.containsKey(X - sum)) {
  
                    // Making sure that all elements are
                    // distinct array elements and an element
                    // is not considered more than once.
                    pair p = mp.get(X - sum);
                    if (p.first != i && p.first != j
                        && p.second != i && p.second != j) {
                        System.out.print(
                            arr[i] + ", " + arr[j]
                            + ", " + arr[p.first]
                            + ", " + arr[p.second]);
                        return;
                    }
                }
            }
        }
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 10, 20, 30, 40, 1, 2 };
        int n = arr.length;
        int X = 91;
        findFourElements(arr, n, X);
    }
}
  
// This code is contributed by Princi Singh

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# A hashing based Python program to find if there are 
# four elements with given summ.
  
# The function finds four elements with given summ X
def findFourElements (arr, n, X):
      
    # Store summs of all pairs in a hash table
    mp = {}
    for i in range(n - 1):
        for j in range(i + 1, n):
            mp[arr[i] + arr[j]] = [i, j]
              
    # Traverse through all pairs and search
    # for X - (current pair summ). 
    for i in range(n - 1):
        for j in range(i + 1, n):
            summ = arr[i] + arr[j]
              
            # If X - summ is present in hash table,     
            if (X - summ) in mp:
                  
                # Making sure that all elements are
                # distinct array elements and an element
                # is not considered more than once.
                p = mp[X - summ]
                if (p[0] != i and p[0] != j and p[1] != i and p[1] != j):
                    print(arr[i], ", ", arr[j], ", ", arr[p[0]], ", ", arr[p[1]], sep ="")
                    return
  
# Driver code
arr = [10, 20, 30, 40, 1, 2]
n = len(arr)
X = 91
findFourElements(arr, n, X)
  
# This is code is contributed by shubhamsingh10

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// A hashing based C# program to find
// if there are four elements with given sum.
using System;
using System.Collections.Generic;
  
class GFG {
    public class pair {
        public int first, second;
        public pair(int first, int second)
        {
            this.first = first;
            this.second = second;
        }
    }
  
    // The function finds four elements
    // with given sum X
    static void findFourElements(int[] arr,
                                 int n, int X)
    {
        // Store sums of all pairs in a hash table
        Dictionary<int,
                   pair>
            mp = new Dictionary<int,
                                pair>();
        for (int i = 0; i < n - 1; i++)
            for (int j = i + 1; j < n; j++)
                if (mp.ContainsKey(arr[i] + arr[j]))
                    mp[arr[i] + arr[j]] = new pair(i, j);
                else
                    mp.Add(arr[i] + arr[j], new pair(i, j));
  
        // Traverse through all pairs and search
        // for X - (current pair sum).
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                int sum = arr[i] + arr[j];
  
                // If X - sum is present in hash table,
                if (mp.ContainsKey(X - sum)) {
  
                    // Making sure that all elements are
                    // distinct array elements and an element
                    // is not considered more than once.
                    pair p = mp[X - sum];
                    if (p.first != i && p.first != j && p.second != i && p.second != j) {
                        Console.Write(arr[i] + ", " + arr[j] + ", " + arr[p.first] + ", " + arr[p.second]);
                        return;
                    }
                }
            }
        }
    }
  
    // Driver Code
    public static void Main(String[] args)
    {
        int[] arr = { 10, 20, 30, 40, 1, 2 };
        int n = arr.Length;
        int X = 91;
        findFourElements(arr, n, X);
    }
}
  
// This code is contributed by 29AjayKumar

chevron_right



Output:

20, 30, 40, 1

Complexity Analysis:

  • Time complexity: O(n^2).
    Nested traversal is needed to store all pairs in the hash Map.
  • Auxiliary Space: O(n^2).
    All n*(n-1) pairs are stored in hash Map so the space required is O(n^2)

Please write comments if you find any of the above codes/algorithms incorrect, or find other ways to solve the same problem.

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details




My Personal Notes arrow_drop_up