在一组序列中查找两个元素的和等于给定的值(快排+两端扫描实现)
题目描述:输入一个值Num,在一组序列中查找两个元素,若他们之和等于输入的值,则将他们挑选出来。
比如:{7,2,9,47,22,32,12,6,11,15}序列,输入14,则输出2和11。先将数组排序:{2,6,7,9,11,12,15,22,32,47},然后从i=0,j=9,i从前向后扫描,j从后向前扫描,如果两个数之和大于输入的Num,则j–,否则i++
// 定义一个结构体,方便函数返回两个参数
typedef struct result
{
int a;
int b;
}result;
// 快速排序法对数组排序
void fastsort(vector<int> &a,int lef, unsigned int rig)
{
int left = lef;
int right = rig;
int i = left;
int j = right;
int pos = a[left];
while(i<j)
{
while(i<j && a[j] >= pos) j--;
if(i<j) swap(a[i],a[j]);
while(i<j && a[i] <= pos) i++;
if(i<j) swap(a[i],a[j]);
}
if (i != left) fastsort(a,left,i-1);
if (j != right) fastsort(a,j+1,right);
}
// 采用两端扫描法
result findTwoNumber(vector<int> &a,int Num)
// 不能写成vector <int>a,因为如果是值传递,在该函数体内部调用fastsort(a,0,len)
// 会产生一个新的拷贝,经过快排之后没法修改数组里的元素顺序
{
struct result res;
unsigned int len = a.size()-1;
fastsort(a,0,len);
for (int i=0;i<=len;i++)
{
cout << a[i] <<endl;
}
int begin = 0;
int end = len;
while (begin < end)
{
if(a[begin] + a[end] < Num)
++begin;
else if(a[begin] + a[end] > Num)
--end;
else
break;
}
res.a = a[begin];
res.b = a[end];
return res;
}
void swap(int i,int j)
{
int temp = i;
j = i;
i = temp;
}
int main()
{
int a[10] = {7,2,9,47,22,32,12,6,11,15};
vector <int> arr;
for (int i=0; i<10; i++)
{
arr.push_back(a[i]);
}
//cout << arr.size()<<endl;
//fastsort(arr,0,arr.size());
result ans = findTwoNumber(arr,14);
cout << ans.a <<endl;
cout << ans.b <<endl;
system("pause");
return 0;
}