您的位置:首页 > 理论基础 > 数据结构算法

算法与数据结构实验题 1.3 寻找幸运值

2017-10-24 18:08 190 查看
算法与数据结构实验题 1.3 寻找幸运值

★ 实验任务

给出两个已按升序排列的数组 a[1..n],b[1..m],如果存在 i,j,使得a[i]+b[j]==k,我们便说已找到幸运值。请你判断能不能找到幸运值。

★数据输入

输入第一行为正整数 n,m,k。(1<=k<=10^9)

第二行为 n 个正整数 a[1..n]。(1<=ai<=10^9)

第三行为 m 个正整数 b[1..m]。(1<=bi<=10^9)

80%的数据 1<=n,m<=1000.

100%的数据 1<=n,m<=100000.

★数据输出

如果能找到幸运值,输出 yes。否则输出 no。

输入示例

3 3 8

1 2 3

4 6 7

输出示例

yes

输入示例

3 3 4

1 2 3

4 6 7

输出示例

no

思路:

若是暴力枚举,则时间复杂度为O(n^2),对于20%的数据会超时。

改进:

k已知,对于a数组中的任意一个数,是否在b数组中存在k-a[i]?可以使用二分查找,时间复杂度降为O(nlnm)。

如果再优化,可以考虑n和m的大小,采取O(nlgm)或者O(mlgn)的算法。

附上代码

#include<iostream>
using namespace std;
int a[100001],b[100001];

int found(int x,int y,int k)        //二分查找
{
int mid=x+(y-x)/2;
if(x>y)                      //查找完毕没有找到答案,返回0
return 0;
else
{
if(b[mid]==k)
return 1;            //找到!返回1
else if(b[mid]>k)
return found(x,mid-1,k);     //找左边
else
return found(mid+1,y,k);     //找右边
}
}

int main()
{
int n,m,k,i,j;
int flag=0;
cin>>n>>m>>k;
for(i=0;i<n;i++)
{
cin>>a[i];
}
for(i=0;i<m;i++)
{
cin>>b[i];
}
for(i=0;i<n;i++)
{
if(k-a[i]<=b[m-1])     //当b数组中有可能存在答案时,调用二分查找
{
if(found(0,m-1,k-a[i]))
{
flag=1;
break;
}
}
}
if(flag)  cout<<"yes"<<endl;
else  cout<<"no"<<endl;
return 0;
}


经ACM大佬指点,对代码进行了进一步改进。

巧妙利用这两个数组递增的特性,仅需存入a数组,用变量cura存a数组的下标,定义cura初始值为n-1,将a数组倒序与数组b中的数字进行求和,若a[cura]+b大于k,则cura自减,继续读入数组b,继续求和判断,如此循环。若a[cura]+b=k,则跳出循环,输出yes;若当cura=0时a[cura]+b仍不等于k,则跳出循环,输出no。

时间复杂度降为O(n),空间复杂度也一并降低。

附上代码

#include<cstdio>
#include<iostream>
using namespace std;
int a[100001], b;
int main()
{
int n,m,k,i,j,cura;
int flag=0;
cin>>n>>m>>k; cura = n - 1;
for(i=0;i<n;i++) scanf("%d", &a[i]);    //相较于C++的cin输入流,C语言的输入函数scanf能节省大量时间
for(i=0;i<m;i++)
{
scanf("%d", &b);
while (cura >= 0 && a[cura] + b > k) cura--;
if (cura < 0)  break;
else if (a[cura] + b == k)
{
cout<<"yes"<<endl; return 0;
}
}
cout<<"no"<<endl;
return 0;
}


感受到了大佬的力量233
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 算法