Open In App
Related Articles

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

Improve Article
Improve
Save Article
Save
Like Article
Like

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.
Recommended Practice

Naive Approach: Using Recursion

Here we will generate all subsets of the given array then we will choose that subset whose size is 3 means that is forming a triplet. In that, we will choose that triplet’s sum whose sum is closest to X.

Code-

C++




#include <bits/stdc++.h>
using namespace std;
 
// Naive recursive function
void findcloseTriplet(int arr[], int n, int x, int count,
                      int sum, int ind, int& ans, int& minm)
{
 
    // Return on reaching to the end of array
    // Here if we picked three element till now then check
    // that sum is closest to our "x" or not
    if (ind == n) {
        if (count == 3) {
            if (abs(x - sum) < minm) {
                minm = abs(x - sum);
                ans = sum;
            }
        }
        return;
    }
 
    // Pick this number
    findcloseTriplet(arr, n, x, count + 1, sum + arr[ind],
                     ind + 1, ans, minm);
 
    // Don't pick this number
    findcloseTriplet(arr, n, x, count, sum, ind + 1, ans,
                     minm);
}
 
int main()
{
    int arr[] = { -1, 2, 1, -4 };
    int x = 1;
    int n = sizeof(arr) / sizeof(arr[0]);
    int minm = INT_MAX;
    int ans;
    findcloseTriplet(arr, n, x, 0, 0, 0, ans, minm);
    cout << ans << endl;
 
    return 0;
}

Java




import java.util.*;
 
public class Main {
    // Naive recursive function
    public static void findCloseTriplet(int[] arr, int n, int x, int count, int sum, int ind, int[] ans, int[] minm) {
        // Return on reaching to the end of array
        // Here if we picked three element till now then check
        // that sum is closest to our "x" or not
        if (ind == n) {
            if (count == 3) {
                if (Math.abs(x - sum) < minm[0]) {
                    minm[0] = Math.abs(x - sum);
                    ans[0] = sum;
                }
            }
            return;
        }
 
        // Pick this number
        findCloseTriplet(arr, n, x, count + 1, sum + arr[ind], ind + 1, ans, minm);
 
        // Don't pick this number
        findCloseTriplet(arr, n, x, count, sum, ind + 1, ans, minm);
    }
 
    public static void main(String[] args) {
        int[] arr = { -1, 2, 1, -4 };
        int x = 1;
        int n = arr.length;
        int[] minm = { Integer.MAX_VALUE };
        int[] ans = new int[1];
        findCloseTriplet(arr, n, x, 0, 0, 0, ans, minm);
        System.out.println(ans[0]);
    }
}

Python3




# Python3 code for the approach
 
# Naive recursive function
def find_close_triplet(arr, n, x, count, sum, ind, ans, minm):
    # Return on reaching to the end of array
    # Here if we picked three element till now then check
    # that sum is closest to our "x" or not
    if ind == n:
        if count == 3:
            if abs(x - sum) < minm[0]:
                minm[0] = abs(x - sum)
                ans[0] = sum
        return
 
    # Pick this number
    find_close_triplet(arr, n, x, count + 1, sum + arr[ind], ind + 1, ans, minm)
 
    # Don't pick this number
    find_close_triplet(arr, n, x, count, sum, ind + 1, ans, minm)
 
# Driver's code
if __name__ == "__main__":
  #Input array
  arr = [-1, 2, 1, -4]
  x = 1
  n = len(arr)
  minm = [float('inf')]
  ans = [0]
   
  # Function Call
  find_close_triplet(arr, n, x, 0, 0, 0, ans, minm)
  print(ans[0])

C#




using System;
 
public class Program
{
// Naive recursive function
public static void FindCloseTriplet(int[] arr, int n, int x, int count, int sum, int ind, ref int ans, ref int minm)
{
// Return on reaching to the end of array
// Here if we picked three element till now then check
// that sum is closest to our "x" or not
if (ind == n)
{
if (count == 3)
{
if (Math.Abs(x - sum) < minm)
{
minm = Math.Abs(x - sum);
ans = sum;
}
}
return;
}
      // Pick this number
    FindCloseTriplet(arr, n, x, count + 1, sum + arr[ind], ind + 1, ref ans, ref minm);
 
    // Don't pick this number
    FindCloseTriplet(arr, n, x, count, sum, ind + 1, ref ans, ref minm);
}
 
public static void Main()
{
    int[] arr = new int[] { -1, 2, 1, -4 };
    int x = 1;
    int n = arr.Length;
    int minm = int.MaxValue;
    int ans = 0;
    FindCloseTriplet(arr, n, x, 0, 0, 0, ref ans, ref minm);
    Console.WriteLine(ans);
}
}

Javascript




// Naive recursive function
function findcloseTriplet(arr, n, x, count, sum, ind, ans, minm) {
    // Return on reaching to the end of array
    // Here if we picked three element till now then check
    // that sum is closest to our "x" or not
    if (ind == n) {
        if (count == 3) {
            if (Math.abs(x - sum) < minm[0]) {
                minm[0] = Math.abs(x - sum);
                ans[0] = sum;
            }
        }
        return;
    }
 
    // Pick this number
    findcloseTriplet(arr, n, x, count + 1, sum + arr[ind], ind + 1, ans, minm);
 
    // Don't pick this number
    findcloseTriplet(arr, n, x, count, sum, ind + 1, ans, minm);
}
 
let arr = [-1, 2, 1, -4];
let x = 1;
let n = arr.length;
let minm = [Number.MAX_VALUE];
let ans = [0];
findcloseTriplet(arr, n, x, 0, 0, 0, ans, minm);
console.log(ans[0]);

Output-

2

Complexity Analysis:

  • Time complexity: O(2n),because of Recursion
  • Auxiliary Space: O(n),Recursion stack space

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 loops with counter i, j and k respectively.
  2. The first loop will start from start to end, the second loop will run from i+1 to end, the third loop will run from j+1 to end.
  3. Check if the difference of the sum of the ith, jth and kth element with the given sum is less than the current minimum or not. Update the current minimum
  4. Print the closest sum.

Implementation:

C++14




// 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 closest 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;
}

Java




// Java implementation of the above approach
class GFG{
     
// Function to return the sum of a
// triplet which is closest to x
public static int solution(int arr[], int x)
{
     
    // To store the closest sum
    int closestSum = Integer.MAX_VALUE;
   
    // Run three nested loops each loop 
    // for each element of triplet
    for(int i = 0; i < arr.length ; i++) 
    {
        for(int j = i + 1; j < arr.length; j++)
        {
            for(int k = j + 1; k < arr.length; k++)
            {
                 
                // Update the closestSum
                if (Math.abs(x - closestSum) >
                    Math.abs(x - (arr[i] + arr[j] + arr[k])))
                    closestSum = (arr[i] + arr[j] + arr[k]);
            
        }
    }
     
    // Return the closest sum found
    return closestSum;
}
 
// Driver code
public static void main(String[] args)
{
    int arr[] = { -1, 2, 1, -4 };
    int x = 1;
     
    System.out.print(solution(arr, x));
}
}
 
// This code is contributed by divyeshrabadiya07

Python3




# Python3 implementation of the above approach
import sys
 
# Function to return the sum of a
# triplet which is closest to x
def solution(arr, x):
 
    # To store the closest sum
    closestSum = sys.maxsize
 
    # Run three nested loops each loop
    # for each element of triplet
    for i in range (len(arr)) :
        for j in range(i + 1, len(arr)):
            for k in range(j + 1, len( arr)):
             
                # 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
if __name__ == "__main__":
     
    arr = [ -1, 2, 1, -4 ]
    x = 1
     
    print(solution(arr, x))
 
# This code is contributed by chitranayal

C#




// C# implementation of the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
 
// Function to return the sum of a
// triplet which is closest to x
static int solution(ArrayList arr, int x)
{
     
    // To store the closest sum
    int closestSum = int.MaxValue;
 
    // Run three nested loops each loop
    // for each element of triplet
    for(int i = 0; i < arr.Count; i++)
    {
        for(int j = i + 1; j < arr.Count; j++)
        {
            for(int k = j + 1; k < arr.Count; k++)
            {
                if (Math.Abs(x - closestSum) >
                    Math.Abs(x - ((int)arr[i] +
                   (int)arr[j] + (int)arr[k])))
                {
                    closestSum = ((int)arr[i] +
                                  (int)arr[j] +
                                  (int)arr[k]);
                }
            }
        }
    }
     
    // Return the closest sum found
    return closestSum;
}
 
// Driver code
public static void Main(string[] args)
{
    ArrayList arr = new ArrayList(){ -1, 2, 1, -4 };
    int x = 1;
    Console.Write(solution(arr, x));
}
}
 
// This code is contributed by rutvik_56

Javascript




<script>
 
// Javascript implementation of the approach
 
// Function to return the sum of a
// triplet which is closest to x
function solution(arr, x)
{
     
    // To store the closest sum
    let closestSum = Number.MAX_VALUE;
 
    // Run three nested loops each loop
    // for each element of triplet
    for(let i = 0; i < arr.length ; i++)
    {
        for(let j =i + 1; j < arr.length; j++)
        {
            for(let k =j + 1; k < arr.length; k++)
            {
                 
                // Update the closestSum
                if (Math.abs(x - closestSum) >
                    Math.abs(x - (arr[i] + arr[j] + arr[k])))
                    closestSum = (arr[i] + arr[j] + arr[k]);
            }
        }
    }
     
    // Return the closest sum found
    return closestSum;
}
 
// Driver code
let arr = [ -1, 2, 1, -4 ];
let x = 1;
 
document.write(solution(arr, x));
 
// This code is contributed by rishavmahato348
 
</script>

Output: 

2

Complexity Analysis:

  • Time complexity: O(N3). 
    Three nested loops are traversing in the array, so time complexity is O(n^3).
  • Space Complexity: 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. The two-pointers algorithm takes 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++14




// 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 closest sum
  //not using INT_MAX to avoid overflowing condition
    int closestSum = 1000000000;
 
    // 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 sum is equal to x, return sum as
              if (sum == x)
              return sum;
            // If the sum is more closer than
            // the current closest sum
            if (abs(x - sum) < abs(x - closestSum)) {
                closestSum = sum;
            }
 
            // If sum is greater than 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;
}

Java




// 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 closest sum
      // Assigning long to avoid overflow condition
      // when array has negative integers
    long 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 than 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 (int)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 */

Python3




# 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 closest 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 than 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

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<int> arr, int x)
{
 
    // Sort the array
    arr.Sort();
 
    // To store the closest 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 than 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

Javascript




<script>
 
// JavaScript implementation of the approach
 
// Function to return the sum of a
// triplet which is closest to x
function solution(arr, x)
{
 
    // Sort the array
    arr.sort((a, b) => a - b);
 
    // To store the closest sum
   // not using INT_MAX to avoid
   // overflowing condition
    let closestSum = 1000000000;
 
    // Fix the smallest number among
    // the three integers
    for (let i = 0; i < arr.length - 2; i++)
    {
 
        // Two pointers initially pointing at
        // the last and the element
        // next to the fixed element
        let ptr1 = i + 1, ptr2 = arr.length - 1;
 
        // While there could be more pairs to check
        while (ptr1 < ptr2) {
 
            // Calculate the sum of the current triplet
            let sum = arr[i] + arr[ptr1] + arr[ptr2];
 
            // If the sum is more closer than
            // the current closest sum
            if (Math.abs(1*x - sum) < Math.abs(1*x - closestSum))
            {
                closestSum = sum;
            }
 
            // If sum is greater than 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
    let arr = [ -1, 2, 1, -4 ];
    let x = 1;
    document.write(solution(arr, x));
 
// This code is contributed by Surbhi Tyagi.
 
</script>

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 Complexity: O(1)
    As no extra space is required.

Last Updated : 03 May, 2023
Like Article
Save Article
Similar Reads
Related Tutorials