问题描述:
计算两个整数x, y的汉明距离,即二进制表达下对应位不同的数量。
解题思路:
看到“对应位不同”,很自然而然的想到了“异或”!
代码:
class Solution {
public int hammingDistance(int x, int y) {
int hammingDis = 0;
int res = x^y;
while(res > 0){
if (res % 2 == 1)
hammingDis ++;
res /= 2;
}
return hammingDis;
}
}
其他:
查看了其他人的解题思路,发现一个特别棒的,只用一句话就解决了问题。
public class Solution {
public int hammingDistance(int x, int y) {
return Integer.bitCount(x ^ y);
}
}
是不是很厉害?进一步查看Integer.bitCount的源码。
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
一开始看完全看不懂,好在找到一个博主详细的解释了这个方法。
(参考链接: https://blog.youkuaiyun.com/cor_twi/article/details/53720640)
其实就是在64位机中,int型占4byes,也就是32bits。该方法的步骤:
1、先两位两位对比,获得每两位1的个数,并存储在原位置上。
例如,10,1的个数为01。发现规律为 i - (i>>>1)。
为了防止移位时前面的影响到后面的高位,因此要与上0x55555555(5的二进制位0101,刚好可以把高位置为0)
2、第二步,在步骤1的前提下,获得每四位1的个数。
例如,步骤以后得到aabb,则每四位1的位数 = aa + bb = (aabb>>>2)+ bb。
同样,为了防止前面的影响到后面的,要与上0x33333333(3的二进制形式为0011)
3、以此类推,依次计算每8位、16位的结果。
4、最后与上0x3f是由于一个int型,至多只会有32个1(32的二进制为100000),即高于6位的高位都无效。