Sum Pair closest to target

Last Updated : 6 Jul, 2026

Given an array arr[] and a number target, find a pair of elements (a, b) in arr[], where a ≤ b whose 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: The pair (5, 20) has sum 25, which is exactly equal to the target. Since its sum is closest to the target, the answer is [5, 20].

Input: arr[] = [5, 2, 7, 1, 4], target = 10
Output: [2, 7]
Explanation: As (4, 5), (2, 7) and (4, 7) both are closest to 10, but absolute difference of (4, 5) is 1, (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: A valid pair requires two elements. Since the array contains only one element, no pair can be formed, so the answer is an empty array.

Try It Yourself
redirect icon

[Naive Approach] Explore all possible pairs - O(n ^ 2) Time and O(1) Space

The idea is to Check every possible pair in the array. For each pair, compute its sum and compare its distance from the target with the best pair found so far. If multiple pairs are equally close, keep the one with the maximum absolute difference.

C++
#include <iostream>
#include <limits.h>
#include <vector>
using namespace std;

vector<int> sumClosest(vector<int> &arr, int target)
{
    int n = arr.size();

    vector<int> res;
    int minDiff = INT_MAX;

    // Generating all possible pairs
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = i + 1; j < n; j++)
        {

            int currSum = arr[i] + arr[j];
            int currDiff = abs(currSum - target);

            // if currDiff is less than minDiff, it indicates
            // that this pair is closer to the target
            if (currDiff < minDiff)
            {
                minDiff = currDiff;
                res = {min(arr[i], arr[j]), max(arr[i], arr[j])};
            }

            // if currDiff is equal to minDiff, find the one with
            // largest absolute difference
            else if (currDiff == minDiff && (res[1] - res[0]) < abs(arr[i] - arr[j]))
            {
                res = {min(arr[i], arr[j]), max(arr[i], arr[j])};
            }
        }
    }
    return res;
}

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

    vector<int> ans = sumClosest(arr, target);

    if (ans.empty())
    {
        cout << "[]";
    }
    else
    {
        cout << "[" << ans[0] << ", " << ans[1] << "]";
    }

    return 0;
}
Java
import java.util.ArrayList;

public class GFG {
    public static ArrayList<Integer> sumClosest(int[] arr,
                                                int target)
    {
        int n = arr.length;

        ArrayList<Integer> res = new ArrayList<>();
        int minDiff = Integer.MAX_VALUE;

        // Generating all possible pairs
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {

                int currSum = arr[i] + arr[j];
                int currDiff = Math.abs(currSum - target);

                // if currDiff is less than minDiff, it
                // indicates that this pair is closer to the
                // target
                if (currDiff < minDiff) {
                    minDiff = currDiff;
                    res.clear();
                    res.add(Math.min(arr[i], arr[j]));
                    res.add(Math.max(arr[i], arr[j]));
                }

                // if currDiff is equal to minDiff, find the
                // one with largest absolute difference
                else if (currDiff == minDiff
                         && (res.get(1) - res.get(0))
                                < Math.abs(arr[i]
                                           - arr[j])) {
                    res.clear();
                    res.add(Math.min(arr[i], arr[j]));
                    res.add(Math.max(arr[i], arr[j]));
                }
            }
        }
        return res;
    }

    public static void main(String[] args)
    {
        int[] arr = { 5, 2, 7, 1, 4 };
        int target = 10;

        ArrayList<Integer> ans = sumClosest(arr, target);

        if (ans.isEmpty()) {
            System.out.println("[]");
        }
        else {
            System.out.println("[" + ans.get(0) + ", "
                               + ans.get(1) + "]");
        }
    }
}
Python
def sumClosest(arr, target):
    n = len(arr)

    res = []
    minDiff = float('inf')

    # Generating all possible pairs
    for i in range(n - 1):
        for j in range(i + 1, n):

            currSum = arr[i] + arr[j]
            currDiff = abs(currSum - target)

            # if currDiff is less than minDiff, it indicates
            # that this pair is closer to the target
            if currDiff < minDiff:
                minDiff = currDiff
                res = [min(arr[i], arr[j]), max(arr[i], arr[j])]

            # if currDiff is equal to minDiff, find the one with
            # largest absolute difference
            elif currDiff == minDiff and (res[1] - res[0]) < abs(arr[i] - arr[j]):
                res = [min(arr[i], arr[j]), max(arr[i], arr[j])]

    return res


if __name__ == '__main__':
    arr = [5, 2, 7, 1, 4]
    target = 10

    ans = sumClosest(arr, target)

    if not ans:
        print('[]')
    else:
        print('[{}, {}]'.format(ans[0], ans[1]))
C#
using System;
using System.Collections.Generic;

class GFG {
    public static List<int> sumClosest(int[] arr,
                                       int target)
    {
        int n = arr.Length;

        List<int> res = new List<int>();
        int minDiff = int.MaxValue;

        // Generating all possible pairs
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                int currSum = arr[i] + arr[j];
                int currDiff = Math.Abs(currSum - target);

                // if currDiff is less than minDiff, it
                // indicates that this pair is closer to the
                // target
                if (currDiff < minDiff) {
                    minDiff = currDiff;
                    res.Clear();
                    res.Add(Math.Min(arr[i], arr[j]));
                    res.Add(Math.Max(arr[i], arr[j]));
                }

                // if currDiff is equal to minDiff, find the
                // one with largest absolute difference
                else if (currDiff == minDiff
                         && (res[1] - res[0]) < Math.Abs(
                                arr[i] - arr[j])) {
                    res.Clear();
                    res.Add(Math.Min(arr[i], arr[j]));
                    res.Add(Math.Max(arr[i], arr[j]));
                }
            }
        }

        return res;
    }

    static void Main()
    {
        int[] arr = { 5, 2, 7, 1, 4 };
        int target = 10;

        List<int> ans = sumClosest(arr, target);

        if (ans.Count == 0) {
            Console.WriteLine("[]");
        }
        else {
            Console.WriteLine("[" + ans[0] + ", " + ans[1]
                              + "]");
        }
    }
}
JavaScript
function sumClosest(arr, target)
{
    let n = arr.length;

    let res = [];
    let minDiff = Number.MAX_SAFE_INTEGER;

    // Generating all possible pairs
    for (let i = 0; i < n - 1; i++) {
        for (let j = i + 1; j < n; j++) {

            let currSum = arr[i] + arr[j];
            let currDiff = Math.abs(currSum - target);

            // if currDiff is less than minDiff, it
            // indicates that this pair is closer to the
            // target
            if (currDiff < minDiff) {
                minDiff = currDiff;
                res = [
                    Math.min(arr[i], arr[j]),
                    Math.max(arr[i], arr[j])
                ];
            }

            // if currDiff is equal to minDiff, find the one
            // with largest absolute difference
            else if (currDiff === minDiff
                     && (res[1] - res[0])
                            < Math.abs(arr[i] - arr[j])) {
                res = [
                    Math.min(arr[i], arr[j]),
                    Math.max(arr[i], arr[j])
                ];
            }
        }
    }
    return res;
}

// Driver Code
let arr = [ 5, 2, 7, 1, 4 ];
let target = 10;

let ans = sumClosest(arr, target);

if (ans.length === 0) {
    console.log("[]");
}
else {
    console.log("[" + ans[0] + "," + ans[1] + "]");
}

Output
[2, 7]

[Better Approach] Binary Search - O(n * log n) Time and O(1) Space

The idea is to first sort the array, then for each element arr[i], use binary search on the subarray arr[i+1…n-1] to find the element closest to the complement (target - arr[i]). This forms a candidate pair whose sum is close to the target.

While performing binary search, three cases arise:

  • If arr[mid] == complement, we've found an exact pair sum equal to target.
  • If arr[mid] < complement, move to the right half -> lo = mid + 1.
  • If arr[mid] > complement, move to the left half -> hi = mid - 1.

Among all such pairs, track the one with the minimum absolute difference from target. If there's a tie, choose the pair with the maximum absolute difference between its elements.

C++
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;

vector<int> sumClosest(vector<int> &arr, int target)
{
    int n = arr.size();
    if (n < 2)
        return {};

    sort(arr.begin(), arr.end());

    vector<int> ans;
    int minDiff = INT_MAX;
    int maxGap = -1;

    for (int i = 0; i < n - 1; i++)
    {

        int complement = target - arr[i];
        int lo = i + 1, hi = n - 1;

        while (lo <= hi)
        {
            int mid = lo + (hi - lo) / 2;

            if (arr[mid] < complement)
                lo = mid + 1;
            else
                hi = mid - 1;
        }

        // Check the insertion position
        if (lo < n)
        {
            int sum = arr[i] + arr[lo];
            int diff = abs(sum - target);
            int gap = arr[lo] - arr[i];

            if (diff < minDiff || (diff == minDiff && gap > maxGap))
            {
                minDiff = diff;
                maxGap = gap;
                ans = {arr[i], arr[lo]};
            }
        }

        // Check the previous position
        if (hi > i)
        {
            int sum = arr[i] + arr[hi];
            int diff = abs(sum - target);
            int gap = arr[hi] - arr[i];

            if (diff < minDiff || (diff == minDiff && gap > maxGap))
            {
                minDiff = diff;
                maxGap = gap;
                ans = {arr[i], arr[hi]};
            }
        }
    }

    return ans;
}

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

    vector<int> ans = sumClosest(arr, target);

    if (ans.empty())
    {
        cout << "[]";
    }
    else
    {
        cout << "[" << ans[0] << ", " << ans[1] << "]";
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;

class GFG {
    public static ArrayList<Integer> sumClosest(int[] arr,
                                                int target)
    {
        int n = arr.length;
        if (n < 2)
            return new ArrayList<>();

        Arrays.sort(arr);

        ArrayList<Integer> ans = new ArrayList<>();
        int minDiff = Integer.MAX_VALUE;
        int maxGap = -1;

        for (int i = 0; i < n - 1; i++) {

            int complement = target - arr[i];
            int lo = i + 1, hi = n - 1;

            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;

                if (arr[mid] < complement)
                    lo = mid + 1;
                else
                    hi = mid - 1;
            }

            // Check the insertion position
            if (lo < n) {
                int sum = arr[i] + arr[lo];
                int diff = Math.abs(sum - target);
                int gap = arr[lo] - arr[i];

                if (diff < minDiff
                    || (diff == minDiff && gap > maxGap)) {
                    minDiff = diff;
                    maxGap = gap;
                    ans.clear();
                    ans.add(arr[i]);
                    ans.add(arr[lo]);
                }
            }

            // Check the previous position
            if (hi > i) {
                int sum = arr[i] + arr[hi];
                int diff = Math.abs(sum - target);
                int gap = arr[hi] - arr[i];

                if (diff < minDiff
                    || (diff == minDiff && gap > maxGap)) {
                    minDiff = diff;
                    maxGap = gap;
                    ans.clear();
                    ans.add(arr[i]);
                    ans.add(arr[hi]);
                }
            }
        }

        return ans;
    }

    public static void main(String[] args)
    {
        int[] arr = { 5, 2, 7, 1, 4 };
        int target = 10;

        ArrayList<Integer> ans = sumClosest(arr, target);

        if (ans.isEmpty()) {
            System.out.println("[]");
        }
        else {
            System.out.println("[" + ans.get(0) + ", "
                               + ans.get(1) + "]");
        }
    }
}
Python
from typing import List
import bisect

def sumClosest(arr, target):
    n = len(arr)
    if n < 2:
        return []

    arr.sort()

    ans = []
    minDiff = float('inf')
    maxGap = -1

    for i in range(n - 1):
        complement = target - arr[i]

        lo = bisect.bisect_left(arr, complement, i + 1, n)
        hi = lo - 1

        # Check the insertion position
        if lo < n:
            curr_sum = arr[i] + arr[lo]
            diff = abs(curr_sum - target)
            gap = arr[lo] - arr[i]

            if diff < minDiff or (diff == minDiff and gap > maxGap):
                minDiff = diff
                maxGap = gap
                ans = [arr[i], arr[lo]]

        # Check the previous position
        if hi > i:
            curr_sum = arr[i] + arr[hi]
            diff = abs(curr_sum - target)
            gap = arr[hi] - arr[i]

            if diff < minDiff or (diff == minDiff and gap > maxGap):
                minDiff = diff
                maxGap = gap
                ans = [arr[i], arr[hi]]

    return ans

if __name__ == '__main__':
    arr = [5, 2, 7, 1, 4]
    target = 10

    ans = sumClosest(arr, target)

    if not ans:
        print("[]")
    else:
        print(f"[{ans[0]}, {ans[1]}]")
C#
using System;
using System.Collections.Generic;

class GFG {
    public static List<int> sumClosest(int[] arr,
                                       int target)
    {
        int n = arr.Length;
        if (n < 2)
            return new List<int>();

        Array.Sort(arr);

        List<int> ans = new List<int>();
        int minDiff = int.MaxValue;
        int maxGap = -1;

        for (int i = 0; i < n - 1; i++) {
            int complement = target - arr[i];
            int lo = i + 1, hi = n - 1;

            while (lo <= hi) {
                int mid = lo + (hi - lo) / 2;

                if (arr[mid] < complement)
                    lo = mid + 1;
                else
                    hi = mid - 1;
            }

            // Check the insertion position
            if (lo < n) {
                int sum = arr[i] + arr[lo];
                int diff = Math.Abs(sum - target);
                int gap = arr[lo] - arr[i];

                if (diff < minDiff
                    || (diff == minDiff && gap > maxGap)) {
                    minDiff = diff;
                    maxGap = gap;
                    ans.Clear();
                    ans.Add(arr[i]);
                    ans.Add(arr[lo]);
                }
            }

            // Check the previous position
            if (hi > i) {
                int sum = arr[i] + arr[hi];
                int diff = Math.Abs(sum - target);
                int gap = arr[hi] - arr[i];

                if (diff < minDiff
                    || (diff == minDiff && gap > maxGap)) {
                    minDiff = diff;
                    maxGap = gap;
                    ans.Clear();
                    ans.Add(arr[i]);
                    ans.Add(arr[hi]);
                }
            }
        }

        return ans;
    }

    static void Main()
    {
        int[] arr = { 5, 2, 7, 1, 4 };
        int target = 10;

        List<int> ans = sumClosest(arr, target);

        if (ans.Count == 0) {
            Console.WriteLine("[]");
        }
        else {
            Console.WriteLine("[" + ans[0] + ", " + ans[1]
                              + "]");
        }
    }
}
JavaScript
function sumClosest(arr, target)
{
    let n = arr.length;
    if (n < 2)
        return [];

    arr.sort((a, b) => a - b);

    let ans = [];
    let minDiff = Number.MAX_SAFE_INTEGER;
    let maxGap = -1;

    for (let i = 0; i < n - 1; i++) {

        let complement = target - arr[i];
        let lo = i + 1, hi = n - 1;

        while (lo <= hi) {
            let mid = Math.floor(lo + (hi - lo) / 2);

            if (arr[mid] < complement)
                lo = mid + 1;
            else
                hi = mid - 1;
        }

        // Check the insertion position
        if (lo < n) {
            let sum = arr[i] + arr[lo];
            let diff = Math.abs(sum - target);
            let gap = arr[lo] - arr[i];

            if (diff < minDiff
                || (diff === minDiff && gap > maxGap)) {
                minDiff = diff;
                maxGap = gap;
                ans = [ arr[i], arr[lo] ];
            }
        }

        // Check the previous position
        if (hi > i) {
            let sum = arr[i] + arr[hi];
            let diff = Math.abs(sum - target);
            let gap = arr[hi] - arr[i];

            if (diff < minDiff
                || (diff === minDiff && gap > maxGap)) {
                minDiff = diff;
                maxGap = gap;
                ans = [ arr[i], arr[hi] ];
            }
        }
    }

    return ans;
}

// Driver COde
let arr = [ 5, 2, 7, 1, 4 ];
let target = 10;

let ans = sumClosest(arr, target);

if (ans.length === 0) {
    console.log("[]");
}
else {
    console.log("[" + ans[0] + "," + ans[1] + "]");
}

Output
[2, 7]

[Expected Approach] Two Pointer Technique - O(n * log n ) Time and O(1) Space

The idea is to first sort the array and use two pointers: left = 0 and right = n - 1. At each step, compute currSum = arr[left] + arr[right] and compare it with the target.

  • If currSum < target, increment left to increase the sum.
  • If currSum > target, decrement right to decrease the sum.
  • If currSum == target, return the current pair immediately, as no pair can have a smaller difference than 0.

Since the search starts with the smallest and largest elements, whenever multiple pairs are equally close to the target, the pair with the maximum absolute difference is encountered first during the traversal. Therefore, no explicit tie-breaking is required.

Let us understand with an example:
Input: arr[] = [5, 2, 7, 1, 4], target = 10

  • Sort the array and initialize two pointers: left = 0 and right = n - 1. Initially, res = [] and minDiff = ∞.
  • Compare the pair (1, 7). Its sum is 8, so update res = [1, 7] and increment left since 8 < 10.
  • Compare (2, 7). Its sum is 9, which is closer to the target, so update res = [2, 7] and increment left.
  • Compare (4, 7) and then (4, 5). Both are equally close to the target. Since the pair with the maximum absolute difference is encountered first during the traversal, the current answer remains unchanged.
  • The pointers eventually meet, ending the traversal. The final answer is [2, 7].
C++
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;

vector<int> sumClosest(vector<int> &arr, int target)
{
    sort(arr.begin(), arr.end());
    int n = arr.size();
    vector<int> res;
    int minDiff = INT_MAX;

    int left = 0, right = n - 1;

    while (left < right)
    {
        int currSum = arr[left] + arr[right];

        // Check if this pair is closer than the closest
        // pair so far
        if (abs(target - currSum) < minDiff)
        {
            minDiff = abs(target - currSum);
            res = {arr[left], arr[right]};
        }

        // If this pair has less sum, move to greater values
        if (currSum < target)
            left++;

        // If this pair has more sum, move to smaller values
        else if (currSum > target)
            right--;

        // If this pair has sum = target, return it
        else
            return res;
    }

    return res;
}

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

    vector<int> ans = sumClosest(arr, target);

    if (ans.empty())
    {
        cout << "[]";
    }
    else
    {
        cout << "[" << ans[0] << ", " << ans[1] << "]";
    }

    return 0;
}
Java
import java.util.ArrayList;
import java.util.Arrays;

public class GFG {
    public static ArrayList<Integer> sumClosest(int[] arr,
                                                int target)
    {
        Arrays.sort(arr);
        int n = arr.length;
        ArrayList<Integer> res = new ArrayList<>();
        int minDiff = Integer.MAX_VALUE;

        int left = 0, right = n - 1;

        while (left < right) {
            int currSum = arr[left] + arr[right];

            // Check if this pair is closer than the closest
            // pair so far
            if (Math.abs(target - currSum) < minDiff) {
                minDiff = Math.abs(target - currSum);
                res.clear();
                res.add(arr[left]);
                res.add(arr[right]);
            }

            // If this pair has less sum, move to greater
            // values
            if (currSum < target)
                left++;

            // If this pair has more sum, move to smaller
            // values
            else if (currSum > target)
                right--;

            // If this pair has sum = target, return it
            else
                return res;
        }

        return res;
    }

    public static void main(String[] args)
    {
        int[] arr = { 5, 2, 7, 1, 4 };
        int target = 10;

        ArrayList<Integer> ans = sumClosest(arr, target);

        if (ans.isEmpty()) {
            System.out.println("[]");
        }
        else {
            System.out.println("[" + ans.get(0) + ", "
                               + ans.get(1) + "]");
        }
    }
}
Python
def sumClosest(arr, target):
    arr.sort()
    n = len(arr)
    res = []
    minDiff = float('inf')

    left = 0
    right = n - 1

    while left < right:
        currSum = arr[left] + arr[right]

        # Check if this pair is closer than the closest
        # pair so far
        if abs(target - currSum) < minDiff:
            minDiff = abs(target - currSum)
            res = [arr[left], arr[right]]

        # If this pair has less sum, move to greater values
        if currSum < target:
            left += 1
        # If this pair has more sum, move to smaller values
        elif currSum > target:
            right -= 1
        # If this pair has sum = target, return it
        else:
            return res

    return res


if __name__ == '__main__':
    arr = [5, 2, 7, 1, 4]
    target = 10

    ans = sumClosest(arr, target)

    if not ans:
        print('[]')
    else:
        print('[{}, {}]'.format(ans[0], ans[1]))
C#
using System;
using System.Collections.Generic;

class GFG {
    public static List<int> sumClosest(int[] arr,
                                       int target)
    {
        Array.Sort(arr);
        int n = arr.Length;
        List<int> res = new List<int>();
        int minDiff = int.MaxValue;

        int left = 0, right = n - 1;

        while (left < right) {
            int currSum = arr[left] + arr[right];

            // Check if this pair is closer than the closest
            // pair so far
            if (Math.Abs(target - currSum) < minDiff) {
                minDiff = Math.Abs(target - currSum);
                res.Clear();
                res.Add(arr[left]);
                res.Add(arr[right]);
            }

            // If this pair has less sum, move to greater
            // values
            if (currSum < target)
                left++;

            // If this pair has more sum, move to smaller
            // values
            else if (currSum > target)
                right--;

            // If this pair has sum = target, return it
            else
                return res;
        }

        return res;
    }

    static void Main()
    {
        int[] arr = { 5, 2, 7, 1, 4 };
        int target = 10;

        List<int> ans = sumClosest(arr, target);

        if (ans.Count == 0) {
            Console.WriteLine("[]");
        }
        else {
            Console.WriteLine("[" + ans[0] + ", " + ans[1]
                              + "]");
        }
    }
}
JavaScript
function sumClosest(arr, target)
{
    arr.sort((a, b) => a - b);
    const n = arr.length;
    let res = [];
    let minDiff = Number.MAX_SAFE_INTEGER;

    let left = 0, right = n - 1;

    while (left < right) {
        const currSum = arr[left] + arr[right];

        // Check if this pair is closer than the closest
        // pair so far
        if (Math.abs(target - currSum) < minDiff) {
            minDiff = Math.abs(target - currSum);
            res = [ arr[left], arr[right] ];
        }

        // If this pair has less sum, move to greater values
        if (currSum < target) {
            left++;
            // If this pair has more sum, move to smaller
            // values
        }
        else if (currSum > target) {
            right--;
            // If this pair has sum = target, return it
        }
        else {
            return res;
        }
    }

    return res;
}

// Driver Code
const arr = [ 5, 2, 7, 1, 4 ];
const target = 10;

const ans = sumClosest(arr, target);

if (ans.length === 0) {
    console.log("[]");
}
else {
    console.log(`[${ans[0]}, ${ans[1]}]`);
}

Output
[2, 7]
Comment