HammingDistance [source code]

public class HammingDistance {
    public int hammingDistance(int x, int y) {
        int xorResult = x ^ y;
        int count = 0;
        while (xorResult > 0) {
            xorResult &= (xorResult - 1);
            count ++;
        }
        return count;
    }
}

这个问题的最优解是直接:
return Integer.bitCount(x ^ y);

当然,这个就有点没意思了, 这里重要的还是学习bit manipulation的技巧;

总体思路是类似的, 先把x and y一个 xor, 把问题转换成为count bit 1 in this number;

这里这个 whileloop 其实是有点难以理解的, 这里的一个key fact 是, x &= (x-1) 这个操作完成的操作就是turn the rightmost bit 1 in x to bit 0;

具体的证明可以假设个位分别是0和1:
如果是1, 很好证明, 个位上的1被消除了;
如果是0, 那么在 x 的右边肯定有一个类似10..0这样的 pattern, 这样一个 pattern 也是 -1的时候承受负担的pattern, 会被变成01..1, 然后整个都被消除, 实际最后达到的效果就是10..0的1被消除了, 也就是rightmost bit 1被消除了;

当然这个底层具体的原理我现在还是不是很清楚, 后面如果有时间看看hacker's delight看看上面有没有讲这个的东西. 只能说这些技巧暂时一边做一边记好了.

记忆这个算法的作用应该是, 比如可以用来turn bit 1 to bit 0 from right to left, one by one;

这里是另外一个解法:

public int hammingDistance(int x, int y) {  
    int xor = x ^ y, count = 0;  
    for (int i=0;i<32;i++) count += (xor >> i) & 1;  
    return count;  
}

或者用一个稍微优化了一下之后的版本:

public int hammingDistance(int x, int y) {  
    int xor = x^y;  
    int res = 0;  
    while(xor!=0) {  
        res+= xor & 1;  
        xor >>= 1;  
    }  
    return res;  
}

这个算法就相对更有指导意义, 算法本身的内核没有前面的那个那么sleek.
这个算法的想法也很简单, 这个问题就是count 1嘛, 所以我们从右到左, 每一个 iteration 数一个1, 数的位置在个位, 数的方式是判断个位是否是1(具体写起来, 使用的 & 1);这个算法的指导意义在于给出了一个比较好用的遍历一个数的 bits 的思路;


Problem Description

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.

Bit Manipulation
Hide Similar Problems (E) Number of 1 Bits (M) Total Hamming Distance

results matching ""

    No results matching ""