寒假每日一题找硬币(个人练习)详细题解+推导证明(第十二天)
Posted 我是管小亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寒假每日一题找硬币(个人练习)详细题解+推导证明(第十二天)相关的知识,希望对你有一定的参考价值。
文章目录
前言
这个寒假每日一题的系列,难度都是比较低的,属于基础题。
今天的题目是来自PAT甲级真题1048。
题目
伊娃喜欢从整个宇宙中收集硬币。
有一天,她去了一家宇宙购物中心购物,结账时可以使用各种硬币付款。
但是,有一个特殊的付款要求:每张帐单,她只能使用恰好两个硬币来准确的支付消费金额。
给定她拥有的所有硬币的面额,请你帮她确定对于给定的金额,她是否可以找到两个硬币来支付。
输入格式
- 第一行包含两个整数 N 和 M,分别表示硬币数量以及需要支付的金额。
- 第二行包含 N 个整数,表示每个硬币的面额。
输出格式
- 输出一行,包含两个整数 V1,V2,表示所选的两个硬币的面额,使得 V1≤V2 并且 V1+V2=M。
- 如果答案不唯一,则输出 V1 最小的解。
- 如果无解,则输出 No Solution。
数据范围
- 1 ≤ N ≤ 105 , 1≤N≤105, 1≤N≤105,
- 1 ≤ M ≤ 1000 1≤M≤1000 1≤M≤1000
输入样例1:
8 15
1 2 8 7 2 4 11 15
输出样例1:
4 11
输入样例2:
7 14
1 8 7 2 4 11 15
输出样例2:
No Solution
详细题解
写法1 O ( n ) O(n) O(n)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_set>
using namespace std;
const int INF = 10000;
int main()
int n, m;
cin >> n >> m;
unordered_set<int> hash;
int v1 = INF, v2;
for (int i = 0; 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 << endl;
return 0;
毫无疑问,这是用空间换时间的做法,利用哈希表进行增删查改,时间复杂度都是 O ( 1 ) O(1) O(1)的,但是相应的空间复杂度都是 O ( n ) O(n) O(n)的。
最后提交,AC😁
推导证明
其实整体思路就是用哈希表去存储查询过但是没有满足条件的数字,然后每次遍历即可。
但是需要注意的是,我们这里查找的是符合条件的最小值,所以,a < b,并且用 v1 和 v2 来存储最终值。
写法2 O ( n l o g n ) O(nlogn) O(nlogn)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100005;
int n, m;
int f[N];
int main()
cin >> n >> m;
for (int i = 0; i < n; ++ i ) cin >> f[i];
sort(f, f + n);
for (int i = 0, j = n - 1; i < j; ++ i )
while (i < j && f[i] + f[j] > m) -- j;
if (i < j && f[i] + f[j] == m)
cout << f[i] << " " << f[j] << endl;
return 0;
puts("No Solution");
return 0;
毫无疑问,双指针可以用来优化哈希表的空间复杂度,但是一般情况下需要排序,所以是 O ( n l o g n ) O(nlogn) O(nlogn)。
最后提交,AC😁
推导证明
双指针需要注意的问题是,排序,如果是乱序的话,没办法保证单调性。
具体的说,就是如果最小值和最大值符合条件,那么即为输出答案,如果不符合条件,那么需要向内侧移动,内侧一定有符合条件的结果。但是如果不是排序的话,内侧未必会符合条件,即无法找到符合条件的结果。
所以,遇事不决,先排序。
举一反三
掌握两种方法的互相优化,如果面试官需要更低的时间复杂度,那么可以使用空间复杂度去置换,如果面试官需要更低的空间复杂度,或者不需要额外的空间复杂度,那么使用双指针。
总结
继续努力,坚持更新,12th打卡。
阿离这个视频真的太美了,爱了爱了
【不夜盛世 扶摇九天】——公孙离惊鸿舞
以上是关于寒假每日一题找硬币(个人练习)详细题解+推导证明(第十二天)的主要内容,如果未能解决你的问题,请参考以下文章
寒假每日一题货仓选址(个人练习)详细题解+推导证明(第一天)
寒假每日一题回文平方(个人练习)详细题解+推导证明(第五天)