两数之和再进化--大餐计数(哈希表的利用)
Posted C_YCBX Py_YYDS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两数之和再进化--大餐计数(哈希表的利用)相关的知识,希望对你有一定的参考价值。
题目
题目解析
读完题目可能大部分人直接暴力两层循环开干,可惜只能通过一半,要是暴力法能过,那也不可能标记为中等题了。
转换思路:我们转换成:两数之和为2的幂的个数,一看到两数之和我们很快会想到利用哈希表的
O(n)
解决方案,我们通过哈希表的key
记录已扫描过的值,value
记录相同值的个数,然后每次通过查找target-nums[i]
即可算出两数之和为target
的次数,而这道题就出现在这个target
不是很确定,但它一定是2的幂
,所以我们可以枚举2的幂为target
得到答案!
- 继续优化算法:
由于我们每次都通过左移得到二的幂来枚举target
,这样在数据很小的情况下明显不利,由于每次只取两个数的和来查看是否为target
,而这两个数的和无论如何都不可能比最大的两数之和要大,所以我们可以先找出最大的那个数,然后*2作为枚举target的上限
.
优化前代码
注意:由于答案需要取模,所以记得每次加法都取模!
class Solution {
public:
const int MOD = 1e9+7;
int countPairs(vector<int>& deliciousness) {
int sz = deliciousness.size();
long long count = 0;
unordered_map<int,long long>check;
for(int i=0;i<sz;i++){
if(i>0)
for(int j=0;j<31;j++){
int p = 1<<j;
auto t = check.find(p-deliciousness[i]);
if(t!=check.end())
count = (count+t->second)%MOD;
}
check[deliciousness[i]]++;
}
return count;
}
};
优化后代码
class Solution {
public:
const int MOD = 1e9+7;
int countPairs(vector<int>& deliciousness) {
int sz = deliciousness.size();
long long count = 0;
int mx = *max_element(deliciousness.begin(),deliciousness.end());
unordered_map<int,long long>check;
for(int i=0;i<sz;i++){
if(i>0)
for(long long p = 1;p<=mx*2;p = p<<1){
auto t = check.find(p-deliciousness[i]);
if(t!=check.end())
count = (count+t->second)%MOD;
}
check[deliciousness[i]]++;
}
return count;
}
};
以上是关于两数之和再进化--大餐计数(哈希表的利用)的主要内容,如果未能解决你的问题,请参考以下文章