题目地址:
https://leetcode.com/problems/total-hamming-distance/
给定一个长 n n n的int数组 A A A,求其两两汉明距离的总和。两个数的汉明距离,是它们的异或之后二进制表示的 1 1 1的个数。
如果 A A A中的数在某个二进制位,是 0 0 0的有 x x x个,是 1 1 1的有 y y y个,那么计算汉明距离总和的时候,这个二进制位的贡献是 x y xy xy。所以只需要将每个二进制位有多少个数在此是 0 0 0多少个在此是 1 1 1计算出来,然后算一下乘积之和即可。代码如下:
public class Solution {
public int totalHammingDistance(int[] nums) {
int[] count0 = new int[32], count1 = new int[32];
for (int num : nums) {
int idx = 0;
while (num != 0) {
if ((num & 1) == 1) {
count1[idx]++;
} else {
count0[idx]++;
}
idx++;
num >>>= 1;
}
while (idx < 32) {
count0[idx]++;
idx++;
}
}
int res = 0;
for (int i = 0; i < 32; i++) {
res += count0[i] * count1[i];
}
return res;
}
}
时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。
C++:
class Solution {
public:
int totalHammingDistance(vector<int>& nums) {
int f[2][32] = {0};
for (auto& x : nums)
for (int i = 0; i < 32; i++) f[x >> i & 1][i]++;
int res = 0;
for (int i = 0; i < 32; i++) res += f[0][i] * f[1][i];
return res;
}
};
时空复杂度一样。