标签:
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).
Array Two Pointers
int threeSumClosest(vector<int>& nums, int target) {
int len_nums=nums.size();
int x=0;
int y=1;
int best_two_sum=abs(nums[0]+nums[1]-target);
for(int i=0;i<len_nums-1;i++)
for(int j=i+1;j<len_nums;j++)
{
if(abs(nums[i]+nums[j]-target)<best_two_sum)
{
x=i;
y=j;
best_two_sum=abs(nums[i]+nums[j]-target);
}
}
int z=0;
int flag=0;
int last_result;
for(int i=0;i<len_nums;i++)
{
if(i!=x&&i!=y&&flag==0)
{z=i;last_result=abs(nums[i]+nums[x]+nums[y]-target);flag=1;}
if(i!=x&&i!=y&&flag==1)
{
if(abs(nums[i]+nums[x]+nums[y]-target)<last_result)
{
z=i;
last_result=abs(nums[i]+nums[x]+nums[y]-target);
}
}
}
return nums[x]+nums[y]+nums[z];
}
*/
//O(n^3)时间复杂度太高了
/*
int threeSumClosest(vector<int>& nums, int target)
{
int len_nums=nums.size();
int result=abs(nums[0]+nums[1]+nums[2]-target);
int l_x=0,l_y=1,l_z=2;
for(int y=1;y<len_nums-1;y++)
{
for(int x=0;x<y;x++)
for(int z=y+1;z<len_nums;z++)
{
if(abs(nums[x]+nums[y]+nums[z]-target)<result)
{
l_x=x;l_y=y;l_z=z;
result=abs(nums[x]+nums[y]+nums[z]-target);
}
}
}
return nums[l_x]+nums[l_y]+nums[l_z];
}
接下来想到干脆直接采用穷举法,试下,也就是时间复杂度为O(n^3)发现不能AC
int threeSumClosest(vector<int>& nums, int target)
{
int len_nums=nums.size();
int result=abs(nums[0]+nums[1]+nums[2]-target);
int l_x=0,l_y=1,l_z=2;
for(int y=1;y<len_nums-1;y++)
{
for(int x=0;x<y;x++)
for(int z=y+1;z<len_nums;z++)
{
if(abs(nums[x]+nums[y]+nums[z]-target)<result)
{
l_x=x;l_y=y;l_z=z;
result=abs(nums[x]+nums[y]+nums[z]-target);
}
}
}
return nums[l_x]+nums[l_y]+nums[l_z];
}
再后来在网上看了下别人的算法,发现有一种还可以,就是在开始的时候就进行排序,这个是O(nlog n),接着枚举一个数,再设立两个指针,一个左指针从0到这个数的位置,一个右指针从最后到这个数的位置,然后当sum<target时将左指针右移,当sum>target时,将右指针向左移,
值得注意的是,在这个移的过程中,当sum<target时,若右移后发现又变成了sum>target,则要将之前的值记录下来,进行比较,另外一个指针也是
同样的道理。这个时间复杂度是O(n^2),
总的为O(nlog n)+O(n^2)=O(n^2)
int threeSumClosest(vector<int>& nums, int target)
{
sort(nums.begin(),nums.end());
int len_nums=nums.size();
int sum;
int sum_reault;
int last_sum=abs(nums[0]+nums[1]+nums[2]-target);
sum_reault=nums[0]+nums[1]+nums[2];
for(int y=1;y<len_nums-1;y++)
{
int x=0;
int z=len_nums-1;
while(x<y&&z>y)
{
if(nums[x]+nums[y]+nums[z]>target)
{
z--;
if(z>y&&nums[x]+nums[y]+nums[z]<target)
{
sum=nums[x]+nums[y]+nums[z+1];
if(abs(sum-target)<last_sum)
{
last_sum=abs(sum-target);
sum_reault=sum;
}
}
}
else if(nums[x]+nums[y]+nums[z]<target)
{
x++;
if(x<y&&nums[x]+nums[y]+nums[z]>target)
{
sum=nums[x-1]+nums[y]+nums[z];
if(abs(sum-target)<last_sum)
{
last_sum=abs(sum-target);
sum_reault=sum;
}
}
}
else
return target;
}
if(x==y)
{
x-=1;
sum=nums[x]+nums[y]+nums[z];
if(abs(sum-target)<last_sum)
{
last_sum=abs(sum-target);
sum_reault=sum;
}
}
if(z==y)
{
z+=1;
sum=nums[x]+nums[y]+nums[z];
if(abs(sum-target)<last_sum)
{
last_sum=abs(sum-target);
sum_reault=sum;
}
}
}
return sum_reault;
}
int main()
{
vector<int> vec;
vec.push_back(0);
vec.push_back(2);
vec.push_back(1);
vec.push_back(-3);
cout<<threeSumClosest(vec,1)<<endl;
}
leetcode_16题——3Sum Closest(两个指针)
标签:
原文地址:http://www.cnblogs.com/yanliang12138/p/4525998.html