【第 15 题】
有一个整数序列 a[n],设计一个算法判断其中是否存在两个元素和恰好等于给定的整数 k。
1.直观想法
思路:先排序,循环一遍每个元素,以当前元素为基准,用二分法寻找该元素之后数组中是否存在元素等于(k-a[i]),时间复杂度O(nlongn)。
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
bool find(int *a,int n,int key,int i)
{
int left=i+1,right=n-1;
while(left<=right)
{
int mid=(left+right)/2;
if(a[mid]==key)
return true;
else if(a[mid]>key)
right=mid-1;
else
left=mid+1;
}
return false;
}
int main()
{
int n,k,i,flag=1; cin>>n>>k;
int a[n];
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
for(i=0;i<n;i++)
{
int key=k-a[i];
if(find(a,n,key,i))
{
cout<<"yes"<<endl;
flag=0;
break;
}
}
if(flag) cout<<"no"<<endl;
return 0;
}
2.参考答案
思路:先将 a 中元素递增排序,然后从两端开始进行判断。对应的程序如下:
#include <bits/stdc++.h>
using namespace std;
bool solve(int a[], int n, int k)
{
sort(a, a + n); //递增排序
int i = 0, j = n - 1;
while (i < j) //区间中存在两个或者以上元素
{
if (a[i] + a[j] == k)
return true;
else if (a[i] + a[j] < k)
i++;
else
j--;
}
return false;
}
void main()
{
int a[] = {1, 2, 4, 5, 3};
int n = sizeof(a) / sizeof(a[0]);
printf("求解结果\n");
int k = 9, i, j;
if (solve(a, n, k, i, j))
printf(" 存在: %d+%d=%d\n", a[i], a[j], k);
else
printf(" 不存在两个元素和为%d\n", k);
int k1 = 10;
if (solve(a, n, k1, i, j))
printf(" 存在: %d+%d=%d\n", a[i], a[j], k1);
else
printf(" 不存在两个元素和为%d\n", k1);
}