Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
For example, given array S = {-1 2 1 -4}, and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
思路1:最容易想到,采用和3Sum相同的方法,先排序,再查找,记录下每个组合的和,找出最接近target的组合。但是显然时间复杂度较高,超时。
class Solution{
public:
int threeSumClosest(vector<int> &num,int target){
int result=INT_MAX;
sort(num.begin(),num.end());
for(vector<int>::iterator a=num.begin();a<num.end()-2;a=upper_bound(a,num.end()-2,*a)){
for(vector<int>::iterator b=a+1;b<num.end()-1;b=upper_bound(b,num.end()-1,*b)){
for(vector<int>::iterator c=b+1;c<num.end();c=upper_bound(c,num.end(),*c)){
if(abs(*a+*b+*c-target)<result)result=*a+*b+*c;
}
}
}
return result;
}
};
思路二:先排序是必须的。然后由于要求找最接近的,那么从两边向其逼近是最快的,可以省略单方向很多无谓的比较。采用第2,3 个数分别从两端开始向中间夹逼
在b<c的情况下:
如果a+b+c的sum>target 那么 c--
如果a+b+c的sum<target 那么 b++
如果a+b+c的sum=target 那么 return
class Solution{
public:
int threeSumClosest(vector<int> &num,int target){
int result=0;
int min_gap=INT_MAX;
sort(num.begin(),num.end());
if(num.size()==3){
return num[0]+num[1]+num[2];
}
for(vector<int>::iterator a=num.begin();a<num.end()-2;a=upper_bound(a,num.end()-2,*a)){
vector<int>::iterator c=num.end()-1;
vector<int>::iterator b=a+1;
while(b<c){ // b!=c
int sum=*a+*b+*c;
int gap=abs(sum-target);
if(sum<target)b=upper_bound(b,num.end()-1,*b);
if(sum>target)c=lower_bound(b,c,*c)-1;
if(sum==target) return sum;
if(gap<min_gap){
result=sum;
min_gap=gap;
}
}
}
return result;
}
};