Given two sorted arrays and a number x, find the pair whose sum is closest to x and the pair has an element from each array.
We are given two arrays ar1[0…m-1] and ar2[0..n-1] and a number x, we need to find the pair ar1[i] + ar2[j] such that absolute value of (ar1[i] + ar2[j] – x) is minimum.
Example:
Input: ar1[] = {1, 4, 5, 7};
ar2[] = {10, 20, 30, 40};
x = 32
Output: 1 and 30
Input: ar1[] = {1, 4, 5, 7};
ar2[] = {10, 20, 30, 40};
x = 50
Output: 7 and 40
We strongly recommend to minimize your browser and try this yourself first.
A Simple Solution is to run two loops. The outer loop considers every element of first array and inner loop checks for the pair in second array. We keep track of minimum difference between ar1[i] + ar2[j] and x.
We can do it in O(n) time using following steps.
1) Merge given two arrays into an auxiliary array of size m+n using merge process of merge sort. While merging keep another boolean array of size m+n to indicate whether the current element in merged array is from ar1[] or ar2[].
2) Consider the merged array and use the linear time algorithm to find the pair with sum closest to x. One extra thing we need to consider only those pairs which have one element from ar1[] and other from ar2[], we use the boolean array for this purpose.
Can we do it in a single pass and O(1) extra space?
The idea is to start from left side of one array and right side of another array, and use the algorithm same as step 2 of above approach. Following is detailed algorithm.
1) Initialize a variable diff as infinite (Diff is used to store the
difference between pair and x). We need to find the minimum diff.
2) Initialize two index variables l and r in the given sorted array.
(a) Initialize first to the leftmost index in ar1: l = 0
(b) Initialize second the rightmost index in ar2: r = n-1
3) Loop while l< length.ar1 and r>=0
(a) If abs(ar1[l] + ar2[r] - sum) < diff then
update diff and result
(b) If (ar1[l] + ar2[r] < sum ) then l++
(c) Else r--
4) Print the result.
Following is the implementation of this approach.
C++
#include <iostream>
#include <climits>
#include <cstdlib>
using namespace std;
void printClosest( int ar1[], int ar2[], int m, int n, int x)
{
int diff = INT_MAX;
int res_l, res_r;
int l = 0, r = n-1;
while (l<m && r>=0)
{
if ( abs (ar1[l] + ar2[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = abs (ar1[l] + ar2[r] - x);
}
if (ar1[l] + ar2[r] > x)
r--;
else
l++;
}
cout << "The closest pair is [" << ar1[res_l] << ", "
<< ar2[res_r] << "] \n" ;
}
int main()
{
int ar1[] = {1, 4, 5, 7};
int ar2[] = {10, 20, 30, 40};
int m = sizeof (ar1)/ sizeof (ar1[0]);
int n = sizeof (ar2)/ sizeof (ar2[0]);
int x = 38;
printClosest(ar1, ar2, m, n, x);
return 0;
}
|
Java
class ClosestPair
{
void printClosest( int ar1[], int ar2[], int m, int n, int x)
{
int diff = Integer.MAX_VALUE;
int res_l = 0 , res_r = 0 ;
int l = 0 , r = n- 1 ;
while (l<m && r>= 0 )
{
if (Math.abs(ar1[l] + ar2[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = Math.abs(ar1[l] + ar2[r] - x);
}
if (ar1[l] + ar2[r] > x)
r--;
else
l++;
}
System.out.print( "The closest pair is [" + ar1[res_l] +
", " + ar2[res_r] + "]" );
}
public static void main(String args[])
{
ClosestPair ob = new ClosestPair();
int ar1[] = { 1 , 4 , 5 , 7 };
int ar2[] = { 10 , 20 , 30 , 40 };
int m = ar1.length;
int n = ar2.length;
int x = 38 ;
ob.printClosest(ar1, ar2, m, n, x);
}
}
|
Python3
import sys
def printClosest(ar1, ar2, m, n, x):
diff = sys.maxsize
l = 0
r = n - 1
while (l < m and r > = 0 ):
if abs (ar1[l] + ar2[r] - x) < diff:
res_l = l
res_r = r
diff = abs (ar1[l] + ar2[r] - x)
if ar1[l] + ar2[r] > x:
r = r - 1
else :
l = l + 1
print ( "The closest pair is [" ,
ar1[res_l], "," ,ar2[res_r], "]" )
ar1 = [ 1 , 4 , 5 , 7 ]
ar2 = [ 10 , 20 , 30 , 40 ]
m = len (ar1)
n = len (ar2)
x = 38
printClosest(ar1, ar2, m, n, x)
|
C#
using System;
class GFG {
static void printClosest( int []ar1,
int []ar2, int m, int n, int x)
{
int diff = int .MaxValue;
int res_l = 0, res_r = 0;
int l = 0, r = n-1;
while (l < m && r >= 0)
{
if (Math.Abs(ar1[l] +
ar2[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = Math.Abs(ar1[l]
+ ar2[r] - x);
}
if (ar1[l] + ar2[r] > x)
r--;
else
l++;
}
Console.Write( "The closest pair is ["
+ ar1[res_l] + ", "
+ ar2[res_r] + "]" );
}
public static void Main()
{
int []ar1 = {1, 4, 5, 7};
int []ar2 = {10, 20, 30, 40};
int m = ar1.Length;
int n = ar2.Length;
int x = 38;
printClosest(ar1, ar2, m, n, x);
}
}
|
PHP
<?php
function printClosest( $ar1 , $ar2 ,
$m , $n , $x )
{
$diff = PHP_INT_MAX;
$res_l ;
$res_r ;
$l = 0;
$r = $n - 1;
while ( $l < $m and $r >= 0)
{
if ( abs ( $ar1 [ $l ] + $ar2 [ $r ] -
$x ) < $diff )
{
$res_l = $l ;
$res_r = $r ;
$diff = abs ( $ar1 [ $l ] +
$ar2 [ $r ] - $x );
}
if ( $ar1 [ $l ] + $ar2 [ $r ] > $x )
$r --;
else
$l ++;
}
echo "The closest pair is [" , $ar1 [ $res_l ] , ", "
, $ar2 [ $res_r ] , "] \n" ;
}
$ar1 = array (1, 4, 5, 7);
$ar2 = array (10, 20, 30, 40);
$m = count ( $ar1 );
$n = count ( $ar2 );
$x = 38;
printClosest( $ar1 , $ar2 , $m , $n , $x );
?>
|
Javascript
<script>
function printClosest( ar1, ar2, m, n, x)
{
let diff = Number.MAX_VALUE;
let res_l, res_r;
let l = 0, r = n-1;
while (l<m && r>=0)
{
if (Math.abs(ar1[l] + ar2[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = Math.abs(ar1[l] + ar2[r] - x);
}
if (ar1[l] + ar2[r] > x)
r--;
else
l++;
}
document.write( "The closest pair is [" + ar1[res_l] + ", "
+ ar2[res_r] + "] </br>" );
}
let ar1 = [1, 4, 5, 7];
let ar2 = [10, 20, 30, 40];
let m = ar1.length;
let n = ar2.length;
let x = 38;
printClosest(ar1, ar2, m, n, x);
</script>
|
Output:
The closest pair is [7, 30]
Time Complexity : O(n)
Auxiliary Space : O(1)
Approach 2: Binary Search:
Since the two input arrays ar1 and ar2 are sorted, the comparison of the sum of the current pair with x essentially performs a binary search on the input array. By moving the left or right index based on the comparison result, the function implicitly divides the input array into two halves at each iteration, and therefore performs a binary search on the input array to find the closest pair.
C++
#include <iostream>
#include <climits>
#include <cstdlib>
using namespace std;
int binarySearch( int ar2[], int left, int right, int x)
{
if (left > right)
return left-1;
int mid = (left + right) / 2;
if (ar2[mid] == x)
return mid;
else if (ar2[mid] > x)
return binarySearch(ar2, left, mid-1, x);
else
return binarySearch(ar2, mid+1, right, x);
}
void printClosest( int ar1[], int ar2[], int m, int n, int x)
{
int diff = INT_MAX;
int res_l, res_r;
int l = 0, r = n - 1;
while (l < m && r >= 0)
{
if ( abs (ar1[l] + ar2[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = abs (ar1[l] + ar2[r] - x);
}
if (ar1[l] + ar2[r] > x)
r--;
else
l++;
}
cout << "The closest pair is [" << ar1[res_l] << ", "
<< ar2[res_r] << "] \n" ;
}
int main()
{
int ar1[] = {1, 4, 5, 7};
int ar2[] = {10, 20, 30, 40};
int m = sizeof (ar1) / sizeof (ar1[0]);
int n = sizeof (ar2) / sizeof (ar2[0]);
int x = 38;
for ( int i = 0; i < m; i++)
{
int index = binarySearch(ar2, 0, n-1, x-ar1[i]);
if (index >= 0 && index < n && abs (ar1[i]+ar2[index]-x) < abs (ar1[i]+ar2[index-1]-x))
{
printClosest(ar1, ar2, m, n, x);
return 0;
}
else if (index > 0 && abs (ar1[i]+ar2[index-1]-x) < abs (ar1[i]+ar2[index]-x))
{
index--;
}
}
}
|
Java
import java.util.*;
public class ClosestSumPair {
public static int binarySearch( int ar2[], int left, int right, int x) {
if (left > right)
return left- 1 ;
int mid = (left + right) / 2 ;
if (ar2[mid] == x)
return mid;
else if (ar2[mid] > x)
return binarySearch(ar2, left, mid- 1 , x);
else
return binarySearch(ar2, mid+ 1 , right, x);
}
public static void printClosest( int ar1[], int ar2[], int m, int n, int x) {
int diff = Integer.MAX_VALUE;
int res_l = 0 , res_r = 0 ;
int l = 0 , r = n - 1 ;
while (l < m && r >= 0 ) {
if (Math.abs(ar1[l] + ar2[r] - x) < diff) {
res_l = l;
res_r = r;
diff = Math.abs(ar1[l] + ar2[r] - x);
}
if (ar1[l] + ar2[r] > x)
r--;
else
l++;
}
System.out.println( "The closest pair is [" + ar1[res_l] + ", " + ar2[res_r] + "]" );
}
public static void main(String args[]) {
int ar1[] = { 1 , 4 , 5 , 7 };
int ar2[] = { 10 , 20 , 30 , 40 };
int m = ar1.length;
int n = ar2.length;
int x = 38 ;
for ( int i = 0 ; i < m; i++) {
int index = binarySearch(ar2, 0 , n- 1 , x-ar1[i]);
if (index >= 0 && index < n && Math.abs(ar1[i]+ar2[index]-x) < Math.abs(ar1[i]+ar2[index- 1 ]-x)) {
printClosest(ar1, ar2, m, n, x);
return ;
} else if (index > 0 && Math.abs(ar1[i]+ar2[index- 1 ]-x) < Math.abs(ar1[i]+ar2[index]-x)) {
index--;
}
}
}
}
|
Python3
import sys
def binarySearch(ar2, left, right, x):
if left > right:
return left - 1
mid = (left + right) / / 2
if ar2[mid] = = x:
return mid
elif ar2[mid] > x:
return binarySearch(ar2, left, mid - 1 , x)
else :
return binarySearch(ar2, mid + 1 , right, x)
def printClosest(ar1, ar2, m, n, x):
diff = sys.maxsize
res_l, res_r = 0 , 0
l, r = 0 , n - 1
while l < m and r > = 0 :
if abs (ar1[l] + ar2[r] - x) < diff:
res_l = l
res_r = r
diff = abs (ar1[l] + ar2[r] - x)
if ar1[l] + ar2[r] > x:
r - = 1
else :
l + = 1
print ( "The closest pair is [{}, {}]" . format (ar1[res_l], ar2[res_r]))
if __name__ = = "__main__" :
ar1 = [ 1 , 4 , 5 , 7 ]
ar2 = [ 10 , 20 , 30 , 40 ]
m = len (ar1)
n = len (ar2)
x = 38
for i in range (m):
index = binarySearch(ar2, 0 , n - 1 , x - ar1[i])
if index > = 0 and index < n and abs (ar1[i] + ar2[index] - x) < abs (ar1[i] + ar2[index - 1 ] - x):
printClosest(ar1, ar2, m, n, x)
break
elif index > 0 and abs (ar1[i] + ar2[index - 1 ] - x) < abs (ar1[i] + ar2[index] - x):
index - = 1
|
C#
using System;
public class MainClass
{
public static int BinarySearch( int [] ar2, int left,
int right, int x)
{
if (left > right)
return left - 1;
int mid = (left + right) / 2;
if (ar2[mid] == x)
return mid;
else if (ar2[mid] > x)
return BinarySearch(ar2, left, mid - 1, x);
else
return BinarySearch(ar2, mid + 1, right, x);
}
public static void PrintClosest( int [] ar1, int [] ar2,
int m, int n, int x)
{
int diff = int .MaxValue;
int res_l = 0, res_r = 0;
int l = 0, r = n - 1;
while (l < m && r >= 0) {
if (Math.Abs(ar1[l] + ar2[r] - x) < diff) {
res_l = l;
res_r = r;
diff = Math.Abs(ar1[l] + ar2[r] - x);
}
if (ar1[l] + ar2[r] > x)
r--;
else
l++;
}
Console.WriteLine( "The closest pair is ["
+ ar1[res_l] + ", " + ar2[res_r]
+ "]" );
}
public static void Main()
{
int [] ar1 = { 1, 4, 5, 7 };
int [] ar2 = { 10, 20, 30, 40 };
int m = ar1.Length;
int n = ar2.Length;
int x = 38;
Array.Sort(ar2);
for ( int i = 0; i < m; i++) {
int index
= BinarySearch(ar2, 0, n - 1, x - ar1[i]);
if (index >= 0 && index < n
&& Math.Abs(ar1[i] + ar2[index] - x)
< Math.Abs(ar1[i] + ar2[index - 1]
- x)) {
PrintClosest(ar1, ar2, m, n, x);
return ;
}
else if (index > 0
&& Math.Abs(ar1[i] + ar2[index - 1]
- x)
< Math.Abs(ar1[i] + ar2[index]
- x)) {
PrintClosest(ar1, ar2, m, n, x);
return ;
}
}
}
}
|
Javascript
function binarySearch(arr, left, right, x) {
if (left > right) {
return left - 1;
}
const mid = Math.floor((left + right) / 2);
if (arr[mid] === x) {
return mid;
} else if (arr[mid] > x) {
return binarySearch(arr, left, mid - 1, x);
} else {
return binarySearch(arr, mid + 1, right, x);
}
}
function printClosest(arr1, arr2, x) {
const m = arr1.length;
const n = arr2.length;
let diff = Infinity;
let res_l = 0,
res_r = 0;
let l = 0,
r = n - 1;
while (l < m && r >= 0) {
if (Math.abs(arr1[l] + arr2[r] - x) < diff) {
res_l = l;
res_r = r;
diff = Math.abs(arr1[l] + arr2[r] - x);
}
if (arr1[l] + arr2[r] > x) {
r -= 1;
} else {
l += 1;
}
console.log(The closest pair is [${arr1[res_l]}, ${arr2[res_r]}]);
}
const arr1 = [1, 4, 5, 7];
const arr2 = [10, 20, 30, 40];
const x = 38;
for (let i = 0; i < arr1.length; i++) {
const index = binarySearch(arr2, 0, arr2.length - 1, x - arr1[i]);
if (
index >= 0 &&
index < arr2.length &&
Math.abs(arr1[i] + arr2[index] - x) <
Math.abs(arr1[i] + arr2[index - 1] - x)
) {
printClosest(arr1, arr2, x);
break ;
} else if (
index > 0 &&
Math.abs(arr1[i] + arr2[index - 1] - x) <
Math.abs(arr1[i] + arr2[index] - x)
) {
index -= 1;
}
}
|
OUTPUT:
The closest pair is [7, 30]
Time Complexity : O(mLogN) , As we are Dividing Arrays using Binary search where.
Auxiliary Space : O(1) As No extra space has been allocated.
Smallest Difference pair of values between two unsorted Arrays
This article is contributed by Harsh. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above