1. 题目来源
链接:1711. 大餐计数
2. 题目解析
一直 TLE
,心态直接爆炸 hh
一开始没想整理周赛题目,字迹很潦草,已经加急下单了类纸膜和阻尼笔尖套,一定会有所改善的!
思路:
- 纯哈希就可以做了。二分当然也可以。
- 枚举第二个数
ai
,再从a1~ai-1
中查找有多少个数能与ai
构成 2 的整次幂。 - 枚举所有数,再在哈希表查找
2^n - ai
在a1~ai-1
出现的次数即可。故总的时间复杂度就是 O ( 22 ∗ n ) O(22*n) O(22∗n)。 - 最后要将
ai
加入到哈希表中。
坑点: unordered_map
即哈希表,不论对其赋值与否都会在哈希表中插入这个值,即 res += hash[t]
,若 t
查找不到则 res += 0
也不影响正确结果,但是这个无用的 t
会被插入到哈希表中,等于说每个数多了 20 倍的无效插入,最终导致哈希表中存在 220w
的数字,导致了一大片的 TLE
。真滴恶心。所以先进行判断,若这个 t
可以和当前枚举的 ai
构成 2 的整次幂,再进行 res += hash[t]
,防止无效值的进入。
- 时间复杂度: O ( 22 ∗ n ) O(22*n) O(22∗n)。
- 空间复杂度: O ( n ) O(n) O(n)
代码:
class Solution {
public:
int countPairs(vector<int>& a) {
unordered_map<int, int> hash;
int res = 0, mod = 1e9 + 7;
for (int i = 0; i < a.size(); i ++ ) {
for (int j = 0; j <= 21; j ++ ) {
int t = (1 << j) - a[i];
if (hash.count(t))
res = (res + hash[t]) % mod;
}
hash[a[i]] ++ ;
}
return res;
}
};