题意
两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。
计算一个数组中,任意两个数之间汉明距离的总和。
示例:
输入: 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,即两数的汉明距离
- 方法二,过滤相同元素,初始排序。
- 方法三:逐位统计
- 数组中元素的范围为从 0到 10^9。由于 109<230.我们可以直接从二进制的第 00 位枚举到第 2929 位。
*参考LeetCode官方
解题步骤
class Solution {
public int totalHammingDistance(int[] nums) {
if(nums.length==0)
return 0;
int sum=0;
//方法一
*//*for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length; j++) {
int x=nums[i] ^ nums [j];
sum+=countNumber(x);
}
}*//*
//方法二
Arrays.sort(nums);
List<Integer> list = new ArrayList<>();
List<Integer> listNumber = new ArrayList<>();
list.add(nums[0]);
int begin = 0;
for (int i = 1; i < nums.length; i++) {
if(nums[i]!=list.get(list.size()-1))
{
list.add(nums[i]);
listNumber.add(i-begin);
begin = i;
}
}
listNumber.add(nums.length-begin);
for (int i = 0; i < list.size(); i++) {
for (int j = i+1; j < list.size(); j++) {
int x = list.get(i) ^ list.get(j);
sum +=countNumber(x)*listNumber.get(i)*listNumber.get(j);
}
}
return sum;
}
public int countNumber(int i)
{
int count;
for(count = 0 ; i > 0 ; count ++)
{
i &= (i-1);
}
return count;
}
}
public int totalHammingDistance(int[] nums) {
int ans = 0, n = nums.length;
for (int i = 0; i < 30; ++i) {
int c = 0;
for (int val : nums) {
c += (val >> i) & 1;
}
ans += c * (n - c);
}
return ans;
}
效果
方法一方法二均超时