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
Explanation:
Sums of triplets:
(-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
Explanation:
Sums of triplets:
1 + 2 + 3 = 6
2 + 3 + 4 = 9
1 + 3 + 4 = 7
...
9 is closest to 10.

Simple 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. Then return the subset whose difference between its sum and X is minimum.



  • Algorithm:
    1. Create three nested loop with counter i, j and k respectively.
    2. First loop will start from start to end, second loop will run from i+1 to end, third loop will run from j+1 to end.
    3. Check if the difference of sum of ith, jth and kth element with given sum is less than the current minimum or not. Update the current minimum
    4. Print the closest sum.
  • Implementation:

    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)
    {
        // To store the closets sum
        int closestSum = INT_MAX;
       
        // Run three nested loops each loop 
        // for each element of triplet
        for (int i = 0; i < arr.size() ; i++) 
        {
            for(int j =i + 1; j < arr.size(); j++)
            {
                for(int k =j + 1; k < arr.size(); k++)
                {
                    //update the closestSum
                    if(abs(x - closestSum) > abs(x - (arr[i] + arr[j] + arr[k])))
                        closestSum =  (arr[i] + arr[j] + arr[k]);
                }    
            }
        }
        // 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

    
    

    Output:

    2
    
  • Complexity Analysis:

    • Time complexity: O(N3).
      There are three nested loops traversing the array, so time complexity is O(n^3).
    • Space Compelxity: O(1).
      As no extra space is required.

Efficient approach: By Sorting the array the efficiency of the algorithm can be improved. This efficient approach uses the two-pointer technique. Traverse the array and fix the first element of the triplet. Now use the Two Pointers algorithm to find the closest number to x – array[i]. Update the closest sum. Two pointers algorithm take linear time so it is better than a nested loop.

  • Algorithm:
    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, Decrease the end pointer to reduce the sum.
      • Update the closest sum found so far.
  • Implementation:

    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(1LL*x - sum) < abs(1LL*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#

    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
    
  • Complexity Analysis:

    • Time complexity: O(N2).
      There are only two nested loops traversing the array, so time complexity is O(n^2). Two pointer algorithm take O(n) time and the first element can be fixed using another nested traversal.
    • Space Compelxity: O(1).
      As no extra space is required.

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details




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.