(AcWing)1532. 找硬币
1>用unordered_set实现哈希
//mathod 1:哈希表 O(n)
#include<iostream>
#include<algorithm>
#include<unordered_set>
using namespace std;
const int INF=10000;
int main()
{
unordered_set<int> hash;
int n,m;
cin>>n>>m;
int v1=INF,v2;
for(int i=0;i<n;i++)
{
int a,b;
cin>>a;
b=m-a;
if(hash.count(b))//h哈希表里b出现的次数,以判断b是否在哈希表里
{
if(a>b)
{
swap(a,b);
}
if(v1>a) v1=a,v2=b;
}
hash.insert(a);
}
if(v1==INF) cout<<"No Solution";
else cout<<v1<<" "<<v2;
return 0;
}
2>双指针
二分法与双指针都要基于有序数列。
当前指针从前往后走的时候,后指针一定单调从后往前走,就可以用双指针算法。
开始是想用二分查找较大的值,但是运用变量之间的关系:
设ar[i]是有序数列。
当ar[i]+ar[j]<=m 且 i<j
若k>j ar[i+1]>ar[i],ar[k]>=ar[j]
ar[i+1]+ar[k]>m 就不用比较下标大于j的数列了
从而减少了时间复杂度。
//mathod 2:双指针 O(nlgn)
#include<iostream>
#include<algorithm>
#include<unordered_set>
using namespace std;
const int N=100005;
int ar[N];
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n;i++)
{
cin>>ar[i];
}
sort(ar,ar+n);
int p1=0,p2=n-1;
int fnd=0;
while(p1<p2)
{
while(ar[p2]+ar[p1]>m) p2--;
if(p1!=p2&&ar[p2]+ar[p1]==m)
{
fnd=1;
break;
}
else p1++;
}
if(fnd==0) cout<<"No Solution";
else cout<<ar[p1]<<" "<<ar[p2];
return 0;
}