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.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up