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;
void findcloseTriplet( int arr[], int n, int x, int count,
int sum, int ind, int & ans, int & minm)
{
if (ind == n) {
if (count == 3) {
if ( abs (x - sum) < minm) {
minm = abs (x - sum);
ans = sum;
}
}
return ;
}
findcloseTriplet(arr, n, x, count + 1, sum + arr[ind],
ind + 1, ans, minm);
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 {
public static void findCloseTriplet( int [] arr, int n, int x, int count, int sum, int ind, int [] ans, int [] minm) {
if (ind == n) {
if (count == 3 ) {
if (Math.abs(x - sum) < minm[ 0 ]) {
minm[ 0 ] = Math.abs(x - sum);
ans[ 0 ] = sum;
}
}
return ;
}
findCloseTriplet(arr, n, x, count + 1 , sum + arr[ind], ind + 1 , ans, minm);
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
def find_close_triplet(arr, n, x, count, sum , ind, ans, minm):
if ind = = n:
if count = = 3 :
if abs (x - sum ) < minm[ 0 ]:
minm[ 0 ] = abs (x - sum )
ans[ 0 ] = sum
return
find_close_triplet(arr, n, x, count + 1 , sum + arr[ind], ind + 1 , ans, minm)
find_close_triplet(arr, n, x, count, sum , ind + 1 , ans, minm)
if __name__ = = "__main__" :
arr = [ - 1 , 2 , 1 , - 4 ]
x = 1
n = len (arr)
minm = [ float ( 'inf' )]
ans = [ 0 ]
find_close_triplet(arr, n, x, 0 , 0 , 0 , ans, minm)
print (ans[ 0 ])
|
C#
using System;
public class Program
{
public static void FindCloseTriplet( int [] arr, int n, int x, int count, int sum, int ind, ref int ans, ref int minm)
{
if (ind == n)
{
if (count == 3)
{
if (Math.Abs(x - sum) < minm)
{
minm = Math.Abs(x - sum);
ans = sum;
}
}
return ;
}
FindCloseTriplet(arr, n, x, count + 1, sum + arr[ind], ind + 1, ref ans, ref minm);
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
function findcloseTriplet(arr, n, x, count, sum, ind, ans, minm) {
if (ind == n) {
if (count == 3) {
if (Math.abs(x - sum) < minm[0]) {
minm[0] = Math.abs(x - sum);
ans[0] = sum;
}
}
return ;
}
findcloseTriplet(arr, n, x, count + 1, sum + arr[ind], ind + 1, ans, minm);
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
#include <bits/stdc++.h>
using namespace std;
int solution(vector< int >& arr, int x)
{
int closestSum = INT_MAX;
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++)
{
if ( abs (x - closestSum) > abs (x - (arr[i] + arr[j] + arr[k])))
closestSum = (arr[i] + arr[j] + arr[k]);
}
}
}
return closestSum;
}
int main()
{
vector< int > arr = { -1, 2, 1, -4 };
int x = 1;
cout << solution(arr, x);
return 0;
}
|
Java
class GFG{
public static int solution( int arr[], int x)
{
int closestSum = Integer.MAX_VALUE;
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++)
{
if (Math.abs(x - closestSum) >
Math.abs(x - (arr[i] + arr[j] + arr[k])))
closestSum = (arr[i] + arr[j] + arr[k]);
}
}
}
return closestSum;
}
public static void main(String[] args)
{
int arr[] = { - 1 , 2 , 1 , - 4 };
int x = 1 ;
System.out.print(solution(arr, x));
}
}
|
Python3
import sys
def solution(arr, x):
closestSum = sys.maxsize
for i in range ( len (arr)) :
for j in range (i + 1 , len (arr)):
for k in range (j + 1 , len ( arr)):
if ( abs (x - closestSum) >
abs (x - (arr[i] +
arr[j] + arr[k]))):
closestSum = (arr[i] +
arr[j] + arr[k])
return closestSum
if __name__ = = "__main__" :
arr = [ - 1 , 2 , 1 , - 4 ]
x = 1
print (solution(arr, x))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
static int solution(ArrayList arr, int x)
{
int closestSum = int .MaxValue;
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 closestSum;
}
public static void Main( string [] args)
{
ArrayList arr = new ArrayList(){ -1, 2, 1, -4 };
int x = 1;
Console.Write(solution(arr, x));
}
}
|
Javascript
<script>
function solution(arr, x)
{
let closestSum = Number.MAX_VALUE;
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++)
{
if (Math.abs(x - closestSum) >
Math.abs(x - (arr[i] + arr[j] + arr[k])))
closestSum = (arr[i] + arr[j] + arr[k]);
}
}
}
return closestSum;
}
let arr = [ -1, 2, 1, -4 ];
let x = 1;
document.write(solution(arr, x));
</script>
|
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
#include <bits/stdc++.h>
using namespace std;
int solution(vector< int >& arr, int x)
{
sort(arr.begin(), arr.end());
int closestSum = 1000000000;
for ( int i = 0; i < arr.size() - 2; i++) {
int ptr1 = i + 1, ptr2 = arr.size() - 1;
while (ptr1 < ptr2) {
int sum = arr[i] + arr[ptr1] + arr[ptr2];
if (sum == x)
return sum;
if ( abs (x - sum) < abs (x - closestSum)) {
closestSum = sum;
}
if (sum > x) {
ptr2--;
}
else {
ptr1++;
}
}
}
return closestSum;
}
int main()
{
vector< int > arr = { -1, 2, 1, -4 };
int x = 1;
cout << solution(arr, x);
return 0;
}
|
Java
import static java.lang.Math.abs;
import java.util.*;
class GFG
{
static int solution(Vector<Integer> arr, int x)
{
Collections.sort(arr);
long closestSum = Integer.MAX_VALUE;
for ( int i = 0 ; i < arr.size() - 2 ; i++)
{
int ptr1 = i + 1 , ptr2 = arr.size() - 1 ;
while (ptr1 < ptr2)
{
int sum = arr.get(i) + arr.get(ptr1) + arr.get(ptr2);
if (abs(x - sum) < abs(x - closestSum))
{
closestSum = sum;
}
if (sum > x)
{
ptr2--;
}
else
{
ptr1++;
}
}
}
return ( int )closestSum;
}
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));
}
}
|
Python3
import sys
def solution(arr, x) :
arr.sort();
closestSum = sys.maxsize;
for i in range ( len (arr) - 2 ) :
ptr1 = i + 1 ; ptr2 = len (arr) - 1 ;
while (ptr1 < ptr2) :
sum = arr[i] + arr[ptr1] + arr[ptr2];
if ( abs (x - sum ) < abs (x - closestSum)) :
closestSum = sum ;
if ( sum > x) :
ptr2 - = 1 ;
else :
ptr1 + = 1 ;
return closestSum;
if __name__ = = "__main__" :
arr = [ - 1 , 2 , 1 , - 4 ];
x = 1 ;
print (solution(arr, x));
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int solution(List< int > arr, int x)
{
arr.Sort();
int closestSum = int .MaxValue;
for ( int i = 0; i < arr.Count - 2; i++)
{
int ptr1 = i + 1, ptr2 = arr.Count - 1;
while (ptr1 < ptr2)
{
int sum = arr[i] + arr[ptr1] + arr[ptr2];
if (Math.Abs(x - sum) <
Math.Abs(x - closestSum))
{
closestSum = sum;
}
if (sum > x)
{
ptr2--;
}
else
{
ptr1++;
}
}
}
return closestSum;
}
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));
}
}
|
Javascript
<script>
function solution(arr, x)
{
arr.sort((a, b) => a - b);
let closestSum = 1000000000;
for (let i = 0; i < arr.length - 2; i++)
{
let ptr1 = i + 1, ptr2 = arr.length - 1;
while (ptr1 < ptr2) {
let sum = arr[i] + arr[ptr1] + arr[ptr2];
if (Math.abs(1*x - sum) < Math.abs(1*x - closestSum))
{
closestSum = sum;
}
if (sum > x) {
ptr2--;
}
else {
ptr1++;
}
}
}
return closestSum;
}
let arr = [ -1, 2, 1, -4 ];
let x = 1;
document.write(solution(arr, x));
</script>
|
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.