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.
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:
- Create three nested loops with counter i, j and k respectively.
- 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.
- 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
- 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> |
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:
- Sort the given array.
- Loop over the array and fix the first element of the possible triplet, arr[i].
- 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> |
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.
Please Login to comment...