Find a triplet in an array whose sum is closest to a given number

Given an array arr[] of N integers and an integer X, the task is to find three integers in arr[] such that the sum is closest to X.

Examples:

Input: arr[] = {-1, 2, 1, -4}, X = 1
Output: 2
(-1) + 2 + 1 = 2
(-1) + 2 + (-4) = -3
2 + 1 + (-4) = -1
2 is closest to 1.

Input: arr[] = {1, 2, 3, 4, -5}, X = 10
Output: 9

Approach: The naive approach is to explore all the subsets of size 3 and keep a track of the difference between X and the sum of this subset. We then return the subset whose difference between its sum and X is minimum.
The time complexity of this naive approach will be O(N3), which is very high for large sized arrays.

Efficient approach: If we sort the given array, we can improve the efficiency of the algorithm. This efficient approach uses the two-pointer technique as follows:

  1. Sort the given array.
  2. Loop over the array and fix the first element of the possible triplet, arr[i].
  3. Then fix two pointers, one at i + 1 and the other at n – 1. And look at the sum,
    • If the sum is smaller than the sum we need to get to, we increase the first pointer.
    • Else, If the sum is bigger, we decrease the end pointer to reduce the sum.
    • We also update the closest sum found so far.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the sum of a
// triplet which is closest to x
int solution(vector<int>& arr, int x)
{
  
    // Sort the array
    sort(arr.begin(), arr.end());
  
    // To store the closets sum
    int closestSum = INT_MAX;
  
    // Fix the smallest number among
    // the three integers
    for (int i = 0; i < arr.size() - 2; i++) {
  
        // Two pointers initially pointing at
        // the last and the element
        // next to the fixed element
        int ptr1 = i + 1, ptr2 = arr.size() - 1;
  
        // While there could be more pairs to check
        while (ptr1 < ptr2) {
  
            // Calculate the sum of the current triplet
            int sum = arr[i] + arr[ptr1] + arr[ptr2];
  
            // If the sum is more closer than
            // the current closest sum
            if (abs(x - sum) < abs(x - closestSum)) {
                closestSum = sum;
            }
  
            // If sum is greater then x then decrement
            // the second pointer to get a smaller sum
            if (sum > x) {
                ptr2--;
            }
  
            // Else increment the first pointer
            // to get a larger sum
            else {
                ptr1++;
            }
        }
    }
  
    // Return the closest sum found
    return closestSum;
}
  
// Driver code
int main()
{
    vector<int> arr = { -1, 2, 1, -4 };
    int x = 1;
    cout << solution(arr, x);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the above approach
import static java.lang.Math.abs;
import java.util.*;
  
class GFG
{
  
// Function to return the sum of a
// triplet which is closest to x
static int solution(Vector<Integer> arr, int x)
{
  
    // Sort the array
    Collections.sort(arr);
  
    // To store the closets sum
    int closestSum = Integer.MAX_VALUE;
  
    // Fix the smallest number among
    // the three integers
    for (int i = 0; i < arr.size() - 2; i++) 
    {
  
        // Two pointers initially pointing at
        // the last and the element
        // next to the fixed element
        int ptr1 = i + 1, ptr2 = arr.size() - 1;
  
        // While there could be more pairs to check
        while (ptr1 < ptr2)
        {
  
            // Calculate the sum of the current triplet
            int sum = arr.get(i) + arr.get(ptr1) + arr.get(ptr2);
  
            // If the sum is more closer than
            // the current closest sum
            if (abs(x - sum) < abs(x - closestSum)) 
            {
                closestSum = sum;
            }
  
            // If sum is greater then x then decrement
            // the second pointer to get a smaller sum
            if (sum > x) 
            {
                ptr2--;
            }
  
            // Else increment the first pointer
            // to get a larger sum
            else
            {
                ptr1++;
            }
        }
    }
  
    // Return the closest sum found
    return closestSum;
}
  
// Driver code
public static void main(String[] args) 
{
    Vector arr = new Vector(Arrays.asList( -1, 2, 1, -4 ));
    int x = 1;
    System.out.println(solution(arr, x));
}
}
  
/* This code is contributed by PrinciRaj1992 */

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
  
import sys
  
# Function to return the sum of a 
# triplet which is closest to x 
def solution(arr, x) : 
  
    # Sort the array 
    arr.sort();
      
    # To store the closets sum
    closestSum = sys.maxsize; 
  
    # Fix the smallest number among 
    # the three integers 
    for i in range(len(arr)-2) : 
  
        # Two pointers initially pointing at 
        # the last and the element 
        # next to the fixed element 
        ptr1 = i + 1; ptr2 = len(arr) - 1
  
        # While there could be more pairs to check 
        while (ptr1 < ptr2) :
  
            # Calculate the sum of the current triplet 
            sum = arr[i] + arr[ptr1] + arr[ptr2]; 
  
            # If the sum is more closer than 
            # the current closest sum 
            if (abs(x - sum) < abs(x - closestSum)) :
                closestSum = sum
  
            # If sum is greater then x then decrement 
            # the second pointer to get a smaller sum 
            if (sum > x) :
                ptr2 -= 1
  
            # Else increment the first pointer 
            # to get a larger sum 
            else :
                ptr1 += 1
  
    # Return the closest sum found 
    return closestSum; 
  
  
# Driver code 
if __name__ == "__main__"
  
    arr = [ -1, 2, 1, -4 ]; 
    x = 1
    print(solution(arr, x)); 
  
# This code is contributed by AnkitRai01

chevron_right


C#

// C# implementation of the above approach
using System;
using System.Collections.Generic;

class GFG
{

// Function to return the sum of a
// triplet which is closest to x
static int solution(List arr, int x)
{

// Sort the array
arr.Sort();

// To store the closets sum
int closestSum = int.MaxValue;

// Fix the smallest number among
// the three integers
for (int i = 0; i < arr.Count - 2; i++) { // Two pointers initially pointing at // the last and the element // next to the fixed element int ptr1 = i + 1, ptr2 = arr.Count - 1; // While there could be more pairs to check while (ptr1 < ptr2) { // Calculate the sum of the current triplet int sum = arr[i] + arr[ptr1] + arr[ptr2]; // If the sum is more closer than // the current closest sum if (Math.Abs(x - sum) < Math.Abs(x - closestSum)) { closestSum = sum; } // If sum is greater then x then decrement // the second pointer to get a smaller sum if (sum > x)
{
ptr2–;
}

// Else increment the first pointer
// to get a larger sum
else
{
ptr1++;
}
}
}

// Return the closest sum found
return closestSum;
}

// Driver code
public static void Main(String[] args)
{
int []ar = { -1, 2, 1, -4 };
List arr = new List(ar);
int x = 1;
Console.WriteLine(solution(arr, x));
}
}

// This code is contributed by Princi Singh

Output:

2


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.