1. 题目来源
链接:477. 汉明距离总和
2. 题目解析
有点考思维,靠数据范围还是能猜出来做法的。
两个数同比特位 0 1 不同的话就贡献一个汉明距离。
显然,针对一个比特位考虑所有的数,若 1 有 a
个,0 有 b
个,则由乘法原理的话,可以贡献 a*b
个数对,也就是可以贡献 a*b
个汉明距离。
所以,针对每个比特位,遍历所有的数,统计当前位比特位 0,1 的个数,相乘即是当前位所能贡献的汉明距离。
其实,这种求方案,求数对等问题,最终答案的范围是必须要考虑的。因为非常容易爆 int
。
在此,当 a=b=n/2
时,取最大值,即 32* (n/2 *n/2)=8 * n^2=8e8
还在 int
范围内,所以答案使用 int
存即可。
时间复杂度: O ( 32 n ) O(32n) O(32n)
空间复杂度: O ( 1 ) O(1) O(1)
代码:
// 直接移位
class Solution {
public:
int totalHammingDistance(vector<int>& nums) {
int res = 0;
for (int i = 31; ~i; i -- ) {
int a = 0, b = 0;
for (auto &x : nums) {
if (x >> i & 1) a ++ ;
else b ++ ;
}
res += a * b;
}
return res;
}
};