解法:时间复杂度为O(n^2)。如果数组已排序,利用解法1的双指针遍历法,可以在O(n)的时间内找到两个数之和等于一个給定的数。我们假设找到的三个数ai,aj,ak有ai<=aj<=ak,要让ai+aj+ak=sum,也就是要ai+aj=sum-ak,设subsum=sum-ak,很容易发现subsum的值只有n个,而确定ai+aj=subsum中的ai,aj只需要O(n)的时间,所以总的时间复杂度为O(nlogn+n*n)=O(n^2)
#include<iostream>
using namespace std;
void swap(int &x,int &y)
{
int temp=x;
x=y;
y=temp;
}
void QuickSort(int data[],int start,int end)
{
int i=start;
int j=end;
int temp=data[start];
if(start<end)
{
while(i!=j)
{
while(j>i&&data[j]>temp)
{
j--;
}
if(j>i)
{
swap(data[i],data[j]);
i++;
}
while(j>i&&data[i]<temp)
{
i++;
}
if(j>i)
{
swap(data[i],data[j]);
j--;
}
}
data[i]=temp;
QuickSort(data,start,i-1);
QuickSort(data,i+1,end);
}
}
bool sum(int*data,int length,int sum,int&v1,int &v2,int &v3)
{
bool found=false;
if(data==NULL||length<=0)
return found;
int ahead=0;
int behind=length-1;
for(int k=0;k<length;k++)
{
if(k==ahead) ahead++;
if(k==behind) behind--;//允许每个数被选取多次
int subSum=sum-data[k];
while(ahead<behind)
{
int curSum=data[ahead]+data[behind];
if(subSum==curSum)
{
v1=data[ahead];
v2=data[behind];
v3=data[k];
found=true;
break;
}
else if(subSum>curSum)
{
ahead++;
}
else
{
behind--;
}
if(k==ahead) ahead++;
if(k==behind) behind--;//允许每个数被选取多次
}
}
return found;
}
void main()
{ int v1;
int v2;
int v3;
int data[]={1,12,3,131};
QuickSort(data,0,3);
if(sum(data,4,135,v1,v2,v3))
{
cout<<v1<<endl;
cout<<v2<<endl;
cout<<v3<<endl;
}
for(int i=0;i<=3;i++)
{
cout<<data[i]<<endl;
}
}