题目
两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。
给出两个整数 x 和 y,计算它们之间的汉明距离。
注意:
0 ≤ x, y < 231.
示例:
输入: x = 1, y = 4
输出: 2
解释:
上面的箭头指出了对应二进制位不同的位置。
思路
要想找到x和y对应二进制的不同位置的个数。我们可以对这两个数进行异或。异或可以使得两个二进制数的对应位置相同为0,相异为1。而这里的1就是题目所说的不同位置。下面介绍三种思路,怎么统计1的个数。
思路一 Integer.bitCount() 来统计1的个数
x和y利用异或(相同为0,相异为1),可以得到一个新的数z,对应二进制1的个数恰好为两个整数二进制不同位置的数目。然后利用Integer.bitCount() 来统计z的1的个数即可。
class Solution {
public int hammingDistance(int x, int y) {
int res = x ^ y;
return Integer.bitCount(res);
}
}
思路二 (z & 1) == 1
如果不用Integer.bitCount()函数呢?怎么统计1的个数呢?可以通过与1异或,并将结果逐步往右移1位。如果末尾是1,那么与1异或则会是1。因为题目限定都是非负数,因此可以算术右移>>,当然可以也无符号右移>>>(高位自动填充0)。
class Solution {
public int hammingDistance(int x, int y) {
int res = x ^ y;
int count = 0;
while(res != 0){
if((res & 1) == 1) count++;
res >>= 1;
}
return count;
}
}
思路三 z = z & (z – 1)
z = z & (z – 1),可以去除z的对应二进制的末尾的1。例如z = 011100,z – 1 就是 011011,那么z & (z – 1)的结果就是011000。将z的最后一个1去掉了。那么我们可以按照这个思路,每次去掉一个1,最后z会为0,如果z不为0,count++。最后返回count即为1的个数。
class Solution {
public int hammingDistance(int x, int y) {
int res = x ^ y;
int count = 0;
while(res != 0){
res = res & (res - 1);
count++;
}
return count;
}
}
总结
位运算 | 含义 | 举例 |
---|---|---|
x ^ 1s = ~x | 与多个1异或,结果为~x | 00111000 ^ 11111111 = 11000111 |
x & 1s = x | 与多个1相与,结果为原来的数 | 00111000 & 11111111 = 00111000 |
x | 0s = x | 与多个0相或,结果为原来的数 | 00111000 | 00000000 = 00111000 |
x &(x – 1) | 结果为去除x对应二进制的最低位的1 | 00111000 & 00110111 = 00110000 |
x &(-x) | 结果为得到x对应的二进制最低位的1 | 00111000 & 11001000 = 00001000 |
1 << (i -1) | 得到第i位为1的数 | i = 4,1 <<(4 – 1) = 1000 |
(1 << i) – 1 | 得到1到i位全为1的数 | i = 4,(1<<4) – 1 = 01111 |
函数 | 意义 |
---|---|
static int Integer.bitCount() | 计算1的个数 |
static int Integer.highestOneBit() | 得到最高位的1 |
static String toBinaryString(int a) | 获取二进制表示的字符串 |
版权声明:本文为zimojiang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。