力扣954:二倍数对数组( 适合使用 map 和 hash 的题目场景)

最近在准备蓝桥杯,今天刷题见到了一道有趣的题目,在这里分享一下。

题目内容:见此处

分析:题目的内容就是找数组中关系两倍的数,找到一对就消一对,消完所有有两倍关系的数之后看是否还有剩余的数没消,要是没有则返回真,反之返回假。更多细节讲解插入在代码里👇

解题代码

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 是比较高效且易于理解的方案

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值