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).这个题目就是求一个数组,给定target,最接近target的3Sum的值。
与3Sum方法相似,n²logn 但是在二分查找的过程中,查找的不再是某个值,而是最接近某个值val的值,只需要在访问过程中更新最接近的值即可。
如果当前的Closest与target相同,则不再查找,直接返回即可。
class Solution {
public:
int closest=100000;
int threeSumClosest(vector<int> &num, int target) {
threeSum(num,target);
return closest;
}
int findClosest(vector<int> &num,int start,int end,int target){
int mi = 10000;
int min_val;
while(start<=end){
int mid = (start+end)/2;
if(num[mid]>target){
end = mid-1;
if(abs(target-num[mid])<mi){
mi = abs(target-num[mid]);
min_val = num[mid];
}
}else if(num[mid]==target){
if(abs(target-num[mid])<mi){
mi = abs(target-num[mid]);
min_val = num[mid];
}
break;
}else{
if(abs(target-num[mid])<mi){
mi = abs(target-num[mid]);
min_val = num[mid];
}
start = mid+1;
}
}
return min_val;
}
void threeSum(vector<int> &num,int target) {
sort(num.begin(),num.end());
int n = num.size();
vector<vector<int> > vv;
vector<int> v;
for(int i=0;i<n-2;){
for(int j=i+1;j<n-1;){
int t2 = target-num[i]-num[j];
int tmp = findClosest(num,j+1,n-1,t2);
if(abs(t2-tmp)<abs(closest-target))
closest = num[i]+num[j]+tmp;
if(closest==target)
return;
j++;
}
int k2 = i;
while(k2<n && num[k2]==num[i])
k2++;
i=k2;
}
}
};
===============================Modified on 29th, April, 2014==================================
妈蛋,看着以前写的代码真心恶心且蛋疼,怎么能那么菜。。
class Solution {
public:
int cur = 1000000;
int threeSumClosest(vector<int> &num, int target) {
sort(num.begin(),num.end());
int n = num.size();
for(int i=0;i<n-2;i++){
for(int j=i+1;j<n-1;j++){
int t = bi_search(num,j+1,target-num[i]-num[j]);
if(t+num[i]+num[j]==target)
return target;
if(abs(t+num[i]+num[j]-target)<abs(cur-target))
cur = t+num[i]+num[j];
}
}
return cur;
}
int bi_search(vector<int> &num,int start,int target){
int c=1000000;
int left=start,right = num.size()-1;
while(left<=right){
int mid = (left+right)/2;
if(num[mid]==target)
return target;
if(num[mid]>target){
if(abs(num[mid]-target)<abs(c-target))
c = num[mid];
right = mid-1;
}else{
if(abs(num[mid]-target)<abs(c-target))
c = num[mid];
left = mid+1;
}
}
return c;
}
};
===============================Modified on 29th, April, 2014==================================