Find four elements a, b, c and d in an array such that a+b = c+d
Given an array of distinct integers, find if there are two pairs (a, b) and (c, d) such that a+b = c+d, and a, b, c and d are distinct elements. If there are multiple answers, then print any of them.
Example:
Input: {3, 4, 7, 1, 2, 9, 8}
Output: (3, 8) and (4, 7)
Explanation: 3+8 = 4+7
Input: {3, 4, 7, 1, 12, 9};
Output: (4, 12) and (7, 9)
Explanation: 4+12 = 7+9
Input: {65, 30, 7, 90, 1, 9, 8};
Output: No pairs found
Expected Time Complexity: O(n2)
A Simple Solution is to run four loops to generate all possible quadruples of the array elements. For every quadruple (a, b, c, d), check if (a+b) = (c+d). The time complexity of this solution is O(n4).
An Efficient Solution can solve this problem in O(n2) time. The idea is to use hashing. We use sum as key and pair as the value in the hash table.
Loop i = 0 to n-1 :
Loop j = i + 1 to n-1 :
calculate sum
If in hash table any index already exist
Then print (i, j) and previous pair
from hash table
Else update hash table
EndLoop;
EndLoop;
Below are implementations of the above idea. In the below implementation, the map is used instead of a hash. The time complexity of map insert and search is actually O(Log n) instead of O(1). So below implementation is O(n2 Log n).
C++
#include<bits/stdc++.h>
using namespace std;
bool findPairs( int arr[], int n)
{
map< int , pair< int , int > > Hash;
for ( int i = 0; i < n; ++i)
{
for ( int j = i + 1; j < n; ++j)
{
int sum = arr[i] + arr[j];
if (Hash.find(sum) == Hash.end())
Hash[sum] = make_pair(i, j);
else
{
pair< int , int > pp = Hash[sum];
cout << "(" << arr[pp.first] << ", " << arr[pp.second]
<< ") and (" << arr[i] << ", " << arr[j] << ")n" ;
return true ;
}
}
}
cout << "No pairs found" ;
return false ;
}
int main()
{
int arr[] = {3, 4, 7, 1, 2, 9, 8};
int n = sizeof arr / sizeof arr[0];
findPairs(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class ArrayElements
{
class pair
{
int first, second;
pair( int f, int s)
{
first = f; second = s;
}
};
boolean findPairs( int arr[])
{
HashMap<Integer,pair> map = new HashMap<Integer,pair>();
int n=arr.length;
for ( int i= 0 ; i<n; ++i)
{
for ( int j=i+ 1 ; j<n; ++j)
{
int sum = arr[i]+arr[j];
if (!map.containsKey(sum))
map.put(sum, new pair(i,j));
else
{
pair p = map.get(sum);
System.out.println( "(" +arr[p.first]+ ", " +arr[p.second]+
") and (" +arr[i]+ ", " +arr[j]+ ")" );
return true ;
}
}
}
return false ;
}
public static void main(String args[])
{
int arr[] = { 3 , 4 , 7 , 1 , 2 , 9 , 8 };
ArrayElements a = new ArrayElements();
a.findPairs(arr);
}
}
|
Python3
def find_pair_of_sum(arr: list , n: int ):
map = {}
for i in range (n):
for j in range (i + 1 , n):
sum = arr[i] + arr[j]
if sum in map :
print (f "{map[sum]} and ({arr[i]}, {arr[j]})" )
return
else :
map [ sum ] = (arr[i], arr[j])
if __name__ = = "__main__" :
arr = [ 3 , 4 , 7 , 1 , 2 , 9 , 8 ]
n = len (arr)
find_pair_of_sum(arr, n)
|
C#
using System;
using System.Collections.Generic;
public class ArrayElements
{
public class pair
{
private readonly ArrayElements outerInstance;
public int first, second;
public pair(ArrayElements outerInstance, int f, int s)
{
this .outerInstance = outerInstance;
first = f;
second = s;
}
}
public virtual bool findPairs( int [] arr)
{
Dictionary< int , pair> map = new Dictionary< int , pair>();
int n = arr.Length;
for ( int i = 0; i < n; ++i)
{
for ( int j = i + 1; j < n; ++j)
{
int sum = arr[i] + arr[j];
if (!map.ContainsKey(sum))
{
map[sum] = new pair( this , i,j);
}
else
{
pair p = map[sum];
Console.WriteLine( "(" + arr[p.first] + ", " + arr[p.second] + ") and (" + arr[i] + ", " + arr[j] + ")" );
return true ;
}
}
}
return false ;
}
public static void Main( string [] args)
{
int [] arr = new int [] {3, 4, 7, 1, 2, 9, 8};
ArrayElements a = new ArrayElements();
a.findPairs(arr);
}
}
|
Javascript
<script>
function findPairs(arr, n) {
let Hash = new Map();
for (let i = 0; i < n; ++i) {
for (let j = i + 1; j < n; ++j) {
let sum = arr[i] + arr[j];
if (!Hash.has(sum))
Hash.set(sum, [i, j]);
else
{
let pp = Hash.get(sum);
document.write( "(" + arr[pp[0]] + ", " + arr[pp[1]] + ") and (" + arr[i] + ", " + arr[j] + ")" );
return true ;
}
}
}
document.write( "No pairs found" );
return false ;
}
let arr = [3, 4, 7, 1, 2, 9, 8];
let n = arr.length
findPairs(arr, n);
</script>
|
Output:
(3, 8) and (4, 7)
Time Complexity : O(n2 logn)
Auxiliary Space: O(n)
Thanks to Gaurav Ahirwar for suggesting above solutions.
Exercise:
1) Extend the above solution with duplicates allowed in array.
2) Further extend the solution to print all quadruples in output instead of just one. And all quadruples should be printed in lexicographical order (smaller values before greater ones). Assume we have two solutions S1 and S2.
S1 : a1 b1 c1 d1 ( these are values of indices in the array )
S2 : a2 b2 c2 d2
S1 is lexicographically smaller than S2 if
a1 < a2 OR
a1 = a2 AND b1 < b2 OR
a1 = a2 AND b1 = b2 AND c1 < c2 OR
a1 = a2 AND b1 = b2 AND c1 = c2 AND d1 < d2
See this for solution of exercise.
Related Article :
Find all pairs (a,b) and (c,d) in array which satisfy ab = cd
Last Updated :
05 Jun, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...