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:

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

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

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

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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<int> 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<int> arr = new List<int>(ar); 
    int x = 1; 
    Console.WriteLine(solution(arr, x)); 
  
// This code is contributed by Princi Singh
chevron_right

Output:
2



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.





Article Tags :