给定一个由N个整数组成的数组arr []和一个整数X ,任务是在arr []中找到三个整数,以使总和最接近X。
例子:
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.
简单方法:天真的方法是探索大小为3的所有子集,并跟踪X和该子集之和之间的差异。然后返回其和与X的差最小的子集。
算法:
- 创建分别具有计数器i,j和k的三个嵌套循环。
- 第一个循环从头到尾开始,第二个循环从i + 1到结束,第三个循环从j + 1到结束。
- 检查给定和的ith,jth和kth元素之和的差是否小于当前最小值。更新当前的最小值
- 打印最接近的总和。
执行:
C++14
// C++ implementation of the approach
#include
using namespace std;
// Function to return the sum of a
// triplet which is closest to x
int solution(vector& 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 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 closets 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 closets 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 closets 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
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the sum of a
// triplet which is closest to x
int solution(vector& arr, int x)
{
// Sort the array
sort(arr.begin(), arr.end());
// To store the closets 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 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 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 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 */
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 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
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 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 arr = new List(ar);
int x = 1;
Console.WriteLine(solution(arr, x));
}
}
// This code is contributed by Princi Singh
输出:
2
复杂度分析:
- 时间复杂度: O(N 3 )。
数组中遍历了三个嵌套循环,因此时间复杂度为O(n ^ 3)。 - 空间复杂度: O(1)。
由于不需要额外的空间。
高效的方法:通过对数组进行排序,可以提高算法的效率。这种有效的方法使用了两指针技术。遍历数组并修复三元组的第一个元素。现在,使用“两指针”算法查找与x – array [i]最接近的数字。更新最接近的总和。两个指针算法需要线性时间,因此它比嵌套循环要好。
算法:
- 对给定的数组进行排序。
- 遍历数组并修复可能的三元组的第一个元素arr [i]。
- 然后固定两个指针,一个指向I + 1 ,另一个指向n-1 。看一下总和
- 如果总和小于我们需要达到的总和,我们将增加第一个指针。
- 否则,如果总和较大,请减小结束指针以减少总和。
- 更新到目前为止找到的最接近的总和。
执行:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the sum of a
// triplet which is closest to x
int solution(vector& arr, int x)
{
// Sort the array
sort(arr.begin(), arr.end());
// To store the closets 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 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 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 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 */
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 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
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 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 arr = new List(ar);
int x = 1;
Console.WriteLine(solution(arr, x));
}
}
// This code is contributed by Princi Singh
输出:
2
复杂度分析:
- 时间复杂度:O(N 2 ) 。
只有两个嵌套循环遍历该数组,因此时间复杂度为O(n ^ 2)。两个指针算法需要O(n)时间,并且可以使用另一个嵌套遍历来固定第一个元素。 - 空间复杂度:O(1) 。
由于不需要额外的空间。