解法一:哈希表
公式转化:
coin[i] + coin[j] = m;
coin[j] = m - coin[i];
判断m-coin[i]是否存在coin[j]与之配对,有则加入,反之则插入coin[i];
由于还要求最小值,所以需要遍历完整个数组。不能一找到就退出!
因为是查找,所以哈希表的O(1)查询更快,所以采用unordered
从左往右找!当枚举到coin[i]时,此时寻找与coin[i]配对的数,必然在[1, i-1];
#include<iostream>
#include<unordered_set>
#include<algorithm>
using namespace std;
const int INF = 1e5 + 10;
unordered_set<int> Hash;
int main()
{
int n, m;
cin >> n >> m;
int v1 = INF, v2;
for (int i=1; i <= n; i ++)
{
int a, b;
cin >> a;
b = m - a;
if (Hash.count(b))
{
Hash.insert(a);
if (a > b) swap(a, b);
if (a < v1) v1 = a, v2 = b;
}
else Hash.insert(a);
}
if (v1 == INF) puts("No Solution");
else cout << v1 << ' ' << v2;
return 0;
}
解法二:排序 + 双指针
sort后,双指针分别指向头和尾,一遇到合法方案就break。
因为是升序的!
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_set>
using namespace std;
const int N = 1e5 + 10, inf = 0x3f3f3f3f;
int coin[N]; //存储每个硬币的价值;
int n, m;
int main()
{
scanf("%d%d", &n, &m);
for (int i=1; i <= n; i ++)
cin >> coin[i];
sort (coin+1, coin+1+n);
int l=1, r=n;
bool flag = false;
while (l < r) //while (l < r)
{
while (coin[l] + coin[r] > m) r --;
while (coin[l] + coin[r] < m) l ++;
if (l < r && coin[l] + coin[r] == m)
{
flag = true;
break;
}
}
if (!flag) puts("No Solution");
else cout << coin[l] << ' ' << coin[r];
return 0;
}