Given a sorted array and a number x, find the pair in array whose sum is closest to x
Last Updated :
19 Sep, 2023
Given a sorted array and a number x, find a pair in an array whose sum is closest to x.
Examples:
Input: arr[] = {10, 22, 28, 29, 30, 40}, x = 54
Output: 22 and 30
Input: arr[] = {1, 3, 4, 7, 10}, x = 15
Output: 4 and 10
Naive Approach:- A simple solution is to consider every pair and keep track of the closest pair (the absolute difference between pair sum and x is minimum). Finally, print the closest pair. The time complexity of this solution is O(n2)
Implementation:-
C++
#include <bits/stdc++.h>
using namespace std;
void printClosest( int arr[], int n, int x)
{
int res_l, res_r;
int temp = INT_MAX;
for ( int i=0;i<n-1;i++)
{
for ( int j=i+1;j<n;j++)
{
if ( abs (arr[i]+arr[j]-x)<temp)
{
res_l=i;
res_r=j;
temp= abs (arr[i]+arr[j]-x);
}
}
}
cout << " The closest pair is " << arr[res_l] << " and " << arr[res_r];
}
int main()
{
int arr[] = {10, 22, 28, 29, 30, 40}, x = 54;
int n = sizeof (arr)/ sizeof (arr[0]);
printClosest(arr, n, x);
return 0;
}
|
Java
import java.util.*;
class GFG {
public static void printClosest( int [] arr, int n, int x)
{
int res_l = 0 ,
res_r = 0 ;
int temp = Integer.MAX_VALUE;
for ( int i = 0 ; i < n - 1 ; i++) {
for ( int j = i + 1 ; j < n; j++) {
if (Math.abs(arr[i] + arr[j] - x) < temp) {
res_l = i;
res_r = j;
temp = Math.abs(arr[i] + arr[j] - x);
}
}
}
System.out.println( "The closest pair is "
+ arr[res_l] + " and "
+ arr[res_r]);
}
public static void main(String[] args)
{
int [] arr = { 10 , 22 , 28 , 29 , 30 , 40 };
int x = 54 ;
int n = arr.length;
printClosest(arr, n, x);
}
}
|
Python3
import sys
def printClosest(arr, n, x):
res_l = res_r = 0
temp = sys.maxsize
for i in range (n - 1 ):
for j in range (i + 1 , n):
if abs (arr[i] + arr[j] - x) < temp:
res_l = i
res_r = j
temp = abs (arr[i] + arr[j] - x)
print ( "The closest pair is" , arr[res_l], "and" , arr[res_r])
arr = [ 10 , 22 , 28 , 29 , 30 , 40 ]
x = 54
n = len (arr)
printClosest(arr, n, x)
|
C#
using System;
public class GFG {
static void PrintClosest( int [] arr, int n, int x)
{
int res_l = 0, res_r = 0;
int temp = int .MaxValue;
for ( int i = 0; i < n - 1; i++) {
for ( int j = i + 1; j < n; j++) {
if (Math.Abs(arr[i] + arr[j] - x) < temp) {
res_l = i;
res_r = j;
temp = Math.Abs(arr[i] + arr[j] - x);
}
}
}
Console.WriteLine( "The closest pair is "
+ arr[res_l] + " and "
+ arr[res_r]);
}
static public void Main( string [] args)
{
int [] arr = { 10, 22, 28, 29, 30, 40 };
int x = 54;
int n = arr.Length;
PrintClosest(arr, n, x);
}
}
|
Javascript
function printClosest(arr, n, x) {
let res_l, res_r;
let temp = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < n - 1; i++) {
for (let j = i + 1; j < n; j++) {
if (Math.abs(arr[i] + arr[j] - x) < temp) {
res_l = i;
res_r = j;
temp = Math.abs(arr[i] + arr[j] - x);
}
}
}
console.log( "The closest pair is " + arr[res_l] + " and " + arr[res_r]);
}
let arr = [10, 22, 28, 29, 30, 40];
let x = 54;
let n = arr.length;
printClosest(arr, n, x);
|
Output
The closest pair is 22 and 30
Time Complexity:- O(N^2)
Auxiliary Space:- O(1)
Binary Search Approach:- The more efficient solution than the above approach is to use Binary Search because the given array is in a sorted format.
Step-by-step algorithm for implementing the above approach:
- Initialize variables:
- l and r to point to the first and last elements of the array, respectively.
- res_l and res_r to store the indexes of the closest pair.
- minDiff to store the current minimum difference.
- Iterate over the array using a loop:
- Set e to the current element.
- While left is less than or equal to right:
- Set mid to the middle element of the subarray.
- If arr[mid] + e is equal to x,
- set res_l to i, res_r to mid, and minDiff to 0. Break out of the loop.
- If abs(arr[mid] + e – x) is less than minDiff,
- set minDiff to abs(arr[mid] + e – x) and res_l to i
- and res_r to mid.
- If arr[mid] + e is less than x, set left to mid + 1.
- Otherwise, set right to mid – 1.
- Set left and right to point to the first and last elements of the remaining subarray, respectively.
- Print the pair with the values of arr[res_l] and arr[res_r].
C++
#include <bits/stdc++.h>
using namespace std;
void closestPair( int arr[], int n, int x) {
int l = 0, r = n - 1;
int res_l, res_r;
int minDiff = INT_MAX;
for ( int i = 0; i < n; i++) {
int e = arr[i];
int left = i + 1, right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] + e == x) {
res_l = i;
res_r = mid;
minDiff = 0;
break ;
}
if ( abs (arr[mid] + e - x) < minDiff) {
minDiff = abs (arr[mid] + e - x);
res_l = i;
res_r = mid;
}
if (arr[mid] + e < x) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
}
cout << "The closest pair is " << arr[res_l] << " and " << arr[res_r];
}
int main() {
int arr[] = {10, 22, 28, 29, 30, 40};
int x = 54;
int n = sizeof (arr) / sizeof (arr[0]);
closestPair(arr, n, x);
return 0;
}
|
Java
import java.util.*;
public class Main {
public static void main(String[] args)
{
int [] arr = { 10 , 22 , 28 , 29 , 30 , 40 };
int x = 54 ;
int n = arr.length;
closestPair(arr, n, x);
}
public static void closestPair( int [] arr, int n, int x)
{
int l = 0 , r = n - 1 ;
int res_l = 0 , res_r = 0 ;
int minDiff = Integer.MAX_VALUE;
for ( int i = 0 ; i < n; i++) {
int e = arr[i];
int left = i + 1 , right = n - 1 ;
while (left <= right) {
int mid = (left + right) / 2 ;
if (arr[mid] + e == x) {
res_l = i;
res_r = mid;
minDiff = 0 ;
break ;
}
if (Math.abs(arr[mid] + e - x) < minDiff) {
minDiff = Math.abs(arr[mid] + e - x);
res_l = i;
res_r = mid;
}
if (arr[mid] + e < x) {
left = mid + 1 ;
}
else {
right = mid - 1 ;
}
}
}
System.out.println( "The closest pair is "
+ arr[res_l] + " and "
+ arr[res_r]);
}
}
|
Python3
import sys
def closestPair(arr, n, x):
l, r = 0 , n - 1
res_l, res_r = 0 , 0
minDiff = sys.maxsize
for i in range (n):
e = arr[i]
left, right = i + 1 , n - 1
while left < = right:
mid = (left + right) / / 2
if arr[mid] + e = = x:
res_l = i
res_r = mid
minDiff = 0
break
if abs (arr[mid] + e - x) < minDiff:
minDiff = abs (arr[mid] + e - x)
res_l = i
res_r = mid
if arr[mid] + e < x:
left = mid + 1
else :
right = mid - 1
print ( "The closest pair is" , arr[res_l], "and" , arr[res_r])
arr = [ 10 , 22 , 28 , 29 , 30 , 40 ]
x = 54
n = len (arr)
closestPair(arr, n, x)
|
C#
using System;
class Program {
static void closestPair( int [] arr, int n, int x) {
int l = 0, r = n - 1;
int res_l = -1, res_r = -1;
int minDiff = int .MaxValue;
for ( int i = 0; i < n; i++) {
int e = arr[i];
int left = i + 1, right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] + e == x) {
res_l = i;
res_r = mid;
minDiff = 0;
break ;
}
if (Math.Abs(arr[mid] + e - x) < minDiff) {
minDiff = Math.Abs(arr[mid] + e - x);
res_l = i;
res_r = mid;
}
if (arr[mid] + e < x) {
left = mid + 1;
}
else {
right = mid - 1;
}
}
}
Console.WriteLine($ "The closest pair is {arr[res_l]} and {arr[res_r]}" );
}
static void Main( string [] args) {
int [] arr = { 10, 22, 28, 29, 30, 40 };
int x = 54;
int n = arr.Length;
closestPair(arr, n, x);
}
}
|
Javascript
function closestPair(arr, n, x) {
let l = 0, r = n - 1;
let res_l, res_r;
let minDiff = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < n; i++) {
let e = arr[i];
let left = i + 1, right = n - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (arr[mid] + e == x) {
res_l = i;
res_r = mid;
minDiff = 0;
break ;
}
if (Math.abs(arr[mid] + e - x) < minDiff) {
minDiff = Math.abs(arr[mid] + e - x);
res_l = i;
res_r = mid;
}
if (arr[mid] + e < x) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
console.log(`The closest pair is ${arr[res_l]} and ${arr[res_r]}`);
}
let arr = [10, 22, 28, 29, 30, 40];
let x = 54;
let n = arr.length;
closestPair(arr, n, x);
|
Output
The closest pair is 22 and 30
Complexity Analysis:
Time Complexity: O(n log n), because we are using a binary search algorithm to search for the pair, and for each element, we are performing a binary search, which has a time complexity of O(logn). Hence, the total time complexity of the approach becomes O(n log n).
Auxiliary Space: O(1), because we are not using any extra space to store the elements of the array or the result. The only extra space used is for storing some variables, which is constant and does not depend on the size of the input.
Efficient Approach:- An efficient solution can find the pair in O(n) time. The idea is similar to method 1 of this post. The following is a 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: l = 0
(b) Initialize second the rightmost index: r = n-1
3) Loop while l < r.
(a) If abs(arr[l] + arr[r] - sum) < diff then
update diff and result
(b) If(arr[l] + arr[r] < sum ) then l++
(c) Else r--
Following is the implementation of the above algorithm.
C++14
#include <bits/stdc++.h>
using namespace std;
void printClosest( int arr[], int n, int x)
{
int res_l, res_r;
int l = 0, r = n-1, diff = INT_MAX;
while (r > l)
{
if ( abs (arr[l] + arr[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = abs (arr[l] + arr[r] - x);
}
if (arr[l] + arr[r] > x)
r--;
else
l++;
}
cout << " The closest pair is " << arr[res_l] << " and " << arr[res_r];
}
int main()
{
int arr[] = {10, 22, 28, 29, 30, 40}, x = 54;
int n = sizeof (arr)/ sizeof (arr[0]);
printClosest(arr, n, x);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
import java.lang.Math;
class CloseSum {
static void printClosest( int arr[], int n, int x)
{
int res_l= 0 , res_r= 0 ;
int l = 0 , r = n- 1 , diff = Integer.MAX_VALUE;
while (r > l)
{
if (Math.abs(arr[l] + arr[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = Math.abs(arr[l] + arr[r] - x);
}
if (arr[l] + arr[r] > x)
r--;
else
l++;
}
System.out.println( " The closest pair is " +arr[res_l]+ " and " + arr[res_r]);
}
public static void main(String[] args)
{
int arr[] = { 10 , 22 , 28 , 29 , 30 , 40 }, x = 54 ;
int n = arr.length;
printClosest(arr, n, x);
}
}
|
Python3
MAX_VAL = 1000000000
def printClosest(arr, n, x):
res_l, res_r = 0 , 0
l, r, diff = 0 , n - 1 , MAX_VAL
while r > l:
if abs (arr[l] + arr[r] - x) < diff:
res_l = l
res_r = r
diff = abs (arr[l] + arr[r] - x)
if arr[l] + arr[r] > x:
r - = 1
else :
l + = 1
print ( 'The closest pair is {} and {}'
. format (arr[res_l], arr[res_r]))
if __name__ = = "__main__" :
arr = [ 10 , 22 , 28 , 29 , 30 , 40 ]
n = len (arr)
x = 54
printClosest(arr, n, x)
|
C#
using System;
class GFG {
static void printClosest( int []arr, int n, int x)
{
int res_l = 0, res_r = 0;
int l = 0, r = n-1, diff = int .MaxValue;
while (r > l)
{
if (Math.Abs(arr[l] + arr[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = Math.Abs(arr[l] + arr[r] - x);
}
if (arr[l] + arr[r] > x)
r--;
else
l++;
}
Console.Write( " The closest pair is " +
arr[res_l] + " and " + arr[res_r]);
}
public static void Main()
{
int []arr = {10, 22, 28, 29, 30, 40};
int x = 54;
int n = arr.Length;
printClosest(arr, n, x);
}
}
|
PHP
<?php
function printClosest( $arr , $n , $x )
{
$res_l ;
$res_r ;
$l = 0;
$r = $n - 1;
$diff = PHP_INT_MAX;
while ( $r > $l )
{
if ( abs ( $arr [ $l ] + $arr [ $r ] - $x ) <
$diff )
{
$res_l = $l ;
$res_r = $r ;
$diff = abs ( $arr [ $l ] + $arr [ $r ] - $x );
}
if ( $arr [ $l ] + $arr [ $r ] > $x )
$r --;
else
$l ++;
}
echo " The closest pair is "
, $arr [ $res_l ] , " and "
, $arr [ $res_r ];
}
$arr = array (10, 22, 28, 29, 30, 40);
$x = 54;
$n = count ( $arr );
printClosest( $arr , $n , $x );
?>
|
Javascript
<script>
function printClosest(arr,n,x)
{
let res_l=0, res_r=0;
let l = 0, r = n-1, diff = Number.MAX_VALUE;
while (r > l)
{
if (Math.abs(arr[l] +
arr[r] - x) < diff)
{
res_l = l;
res_r = r;
diff = Math.abs(arr[l] + arr[r] - x);
}
if (arr[l] + arr[r] > x)
r--;
else
l++;
}
document.write(
" The closest pair is " +arr[res_l]+ " and " + arr[res_r]
);
}
let arr = [10, 22, 28, 29, 30, 40], x = 54;
let n = arr.length;
printClosest(arr, n, x);
</script>
|
Output
The closest pair is 22 and 30
Time Complexity: O(n), where n is the length of an Array.
Auxiliary Space: O(1)
Please Login to comment...