最近在准备蓝桥杯,今天刷题见到了一道有趣的题目,在这里分享一下。
题目内容:见此处
分析:题目的内容就是找数组中关系两倍的数,找到一对就消一对,消完所有有两倍关系的数之后看是否还有剩余的数没消,要是没有则返回真,反之返回假。更多细节讲解插入在代码里👇
解题代码
class Solution {
public:
bool canReorderDoubled(vector<int>& arr) {
map<int, int> map;
for (auto& num : arr) {
map[num]++;
//以元素值为 key,相同元素个数为 value,将数组内容转入map中处理
}
if (map[0] % 2 != 0) {
//如果数组中的 0 的个数为单数,则题设条件必不成立,因为 0 的
//两倍也是 0,当 0 的个数为单数的时候,其两两相消会剩下一个 0,导致返回false
return false;
}
map[0] = 0;// 0 的个数为偶数,与 0 只有一个效果一样,简化运算量将其记作 0 个
for (auto& [k, v] : map) {
if (v = 0) continue;//当前 value 为 0 说明没有此元素值可以消了,所以 continue
if (map.count(k * 2)) {
int num = min(v, map[2 * k]);//数组中有几个 k 和 2*k ,谁的数目小就为num
map[k] -= num;
map[k * 2] -= num;//因为数组中 k 和 2*k 要两两抵消,所以这两句目的是抵消全部的数目少的那个元素值
}
}
for (auto& [k, v] : map) {
//这个 for 循环判断是否有元素的数目没被抵消完,如果有,则说明某一个 k 与其 2*k 数目不均等,
//就不满足题设条件了,所以返回 false
if (v > 0) {
return false;
}
}
//所有的元素都已经全部抵消完毕,返回true
return true;
}
};
总结
这道题是一道关于对 hash 表或者 map 的操作题,在刷题过程中涉及到元素数目的问题,元素数目构成某种规定的问题时 hash 表和 map 是比较高效且易于理解的方案