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