The Hamming distance between two integers is the number of positions at which the corresponding bits are different.
Given two integers x
and y
, calculate the Hamming distance.
Note:
0 ≤ x
, y
< 231.
Example:
Input: x = 1, y = 4 Output: 2 Explanation: 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ The above arrows point to positions where the corresponding bits are different.
这道题让我求两个数字之间的汉明距离,题目中解释的很清楚了,两个数字之间的汉明距离就是其二进制数对应位不同的个数,那么最直接了当的做法就是按位分别取出两个数对应位上的数并异或,我们知道异或的性质上相同的为0,不同的为1,我们只要把为1的情况累加起来就是汉明距离了,参见代码如下:
解法一:
class Solution { public: int hammingDistance(int x, int y) { int res = 0; for (int i = 0; i < 32; ++i) { if ((x & (1 << i)) ^ (y & (1 << i))) { ++res; } } return res; } };
我们可以对上面的代码进行优化,我们可以一开始直接将两个数字异或起来,然后我们遍历异或结果的每一位,统计为1的个数,也能达到同样的效果,参见代码如下:
解法二:
class Solution { public: int hammingDistance(int x, int y) { int res = 0, exc = x ^ y; for (int i = 0; i < 32; ++i) { res += (exc >> i) & 1; } return res; } };
经过副博主@fantasywindy的提醒,上面的遍历每一位的方法并不高效,还可以进一步优化,假如数为num, num & (num - 1)可以快速地移除最右边的bit 1, 一直循环到num为0, 总的循环数就是num中bit 1的个数。参见代码如下:
解法三:
class Solution { public: int hammingDistance(int x, int y) { int res = 0, exc = x ^ y; while (exc) { ++res; exc &= (exc - 1); } return res; } };
我们再来看一种递归的写法,非常的简洁,递归终止的条件是当两个数异或为0时,表明此时两个数完全相同,我们返回0,否则我们返回异或和对2取余加上对x/2和y/2调用递归的结果。异或和对2取余相当于检查最低位是否相同,而对x/2和y/2调用递归相当于将x和y分别向右移动一位,这样每一位都可以比较到,也能得到正确结果,参见代码如下:
解法四:
class Solution { public: int hammingDistance(int x, int y) { if ((x ^ y) == 0) return 0; return (x ^ y) % 2 + hammingDistance(x / 2, y / 2); } };
参考资料:
https://discuss.leetcode.com/topic/72089/java-3-line-solution
https://discuss.leetcode.com/topic/72093/java-1-line-solution-d
https://discuss.leetcode.com/topic/72289/0ms-c-two-line-solution