两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。
计算一个数组中,任意两个数之间汉明距离的总和。
示例:
输入: 4, 14, 2
输出: 6
解释: 在二进制表示中,4表示为0100,14表示为1110,2表示为0010。(这样表示是为了体现后四位之间关系)
所以答案为:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.
注意:
数组中元素的范围为从 0到 10^9。
数组的长度不超过 10^4。
思路:
汉明距离可以让两个整数进行异或运算,然后计算得到的数字的二进制1的个数即可
尝试了一下暴力法,超时
class Solution {
public:
int HammingDistance(int a, int b)
{
int temp = a^b;
int count = 0;
while (temp)
{
++count;
temp = (temp - 1)&temp;
}
return count;
}
int totalHammingDistance(vector<int>& nums)
{
if (nums.size() <= 1)
return 0;
int res = 0;
for (int i = 0; i < nums.size() - 1; ++i)
for (int j = i + 1; j < nums.size(); ++j)
res += HammingDistance(nums[i], nums[j]);
return res;
}
};
思路2:
这次我们换个思路,我们尝试在一次循环中计算整个数组的所有数字的二进制第一位是1的个数和0的个数,这样一次循环完了第一位的汉明距离就是countOf1*countOf0,然后下一次循环计算所有数字的第二位,以此类推
维持一个temp记录数组中数字变成0 的个数,当temp==nums.size(),说明所有数字都已经移位完了,退出循环
class Solution {
public:
int totalHammingDistance(vector<int>& nums)
{
if (nums.size() <= 1)
return 0;
int res = 0;
for (int i = 0; i < 32; ++i)//最多是32位的整数
{
int countOf1 = 0,countOf0=0;
int temp = 0;
for (int j = 0; j < nums.size(); ++j)
{
if (nums[j] & 1)
countOf1++;
else
countOf0++;
nums[j] >>= 1;
temp += nums[j] == 0 ? 1 : 0;
}
res += countOf0*countOf1;
if (temp == nums.size())break;
}
return res;
}
};