Open In App

2 Sum – Pair Sum Closest to Target using Binary Search

Last Updated : 07 Jan, 2025
Comments
Improve
Suggest changes
85 Likes
Like
Report

Given an array arr[] of n integers and an integer target, the task is to find a pair in arr[] such that it’s sum is closest to target.

Note: Return the pair in sorted order and if there are multiple such pairs return the pair with maximum absolute difference. If no such pair exists return an empty array.

Examples:

Input: arr[] = [10, 30, 20, 5], target = 25
Output: [5, 20]
Explanation: Out of all the pairs, [5, 20] has sum = 25 which is closest to 25.

Input: arr[] = [5, 2, 7, 1, 4], target = 10
Output: [2, 7]
Explanation: As (4, 7) and (2, 7) both are closest to 10, but absolute difference of (2, 7) is 5 and (4, 7) is 3. Hence,[2, 7] has maximum absolute difference and closest to target.

Input: arr[] = [10], target = 10
Output: []
Explanation: As the input array has only 1 element, return an empty array.

We have already discussed the Naive and Expected Approach in 2 Sum – Pair Sum Closest to Target. In this post, we will be discussing the Binary Search based approach.

Using Binary Search – O(2*n log(n)) Time and O(1) Space

As the given input array is sorted, so we can use this property to find the second element in a pair more efficiently using binary search. First, iterate over the array and for each element arr[i], binary search on the remaining array for the element closest to its complement, that is (target – arr[i]). While searching, we can have three cases:

  • arr[mid] == complement: we have found an element which can pair with arr[i] to give pair sum = target.
  • arr[mid] < complement: we need to search for a greater element, so update lo = mid + 1.
  • arr[mid] > complement: we need to search for a lesser element, so update hi = mid – 1.

Note: In this approach, we don’t need to separately handle the case when there is a tie between pairs and we need to select the one with maximum absolute difference. This is because we are selecting the first element of the pair in increasing order, so if we have a tie between two pairs, we can always choose the first pair.

C++
// C++ Code to find pair with closest sum using Binary Search

#include <bits/stdc++.h>
using namespace std;

// Find element closest to complement using binary search
int findClosest(vector<int>& arr, int lo, int hi, int complement) {
    int res = arr[lo];
    
    while (lo <= hi) {
        int mid = (lo + hi) / 2;

        // Update answer if we find a closer element
        if (abs(arr[mid] - complement) < abs(res - complement))
            res = arr[mid];
      
        // If there is a tie, then we pick the larger value
        else if(abs(arr[mid] - complement) == abs(res - complement))
            res = max(res, arr[mid]);   
        
        if (arr[mid] == complement) 
            return arr[mid];
        else if (arr[mid] < complement)
            lo = mid + 1;
        else 
            hi = mid - 1;
    }

    return res;
}

// Find pair with sum closest to target and max absolute difference
vector<int> sumClosest(vector<int>& arr, int target) {
  
    int n = arr.size();
    sort(arr.begin(), arr.end());
    vector<int> res;
    int minDiff = INT_MAX;

    for (int i = 0; i < n - 1; i++) {
      
        // Use binary search in arr[i+1...n-1] to  
        // find the element closest to (target - arr[i])
        int complement = target - arr[i];
        int closest = findClosest(arr, i + 1, n - 1, complement);
      
        int currDiff = abs(target - arr[i] - closest);
        if(currDiff < minDiff) {
        	minDiff = currDiff;
            res = {arr[i], closest};
        }
    }

    return res;
}

int main() {
    vector<int> arr = {5, 2, 7, 1, 4};
    int target = 10;

    vector<int> res = sumClosest(arr, target);
    if(res.size() > 0)
    	cout << res[0] << " " << res[1];
    return 0;
}
C Java Python C# JavaScript

Output
2 7




Next Article

Similar Reads