leetcode刷题(7)——461.汉明距离

一、题目

两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。

给出两个整数 x 和 y,计算它们之间的汉明距离。

注意:

0 ≤ x, y < 2^31.

示例:
在这里插入图片描述

二、思路及代码实现

利用异或运算(xor),运算规则是进行运算的两位,相同则结果为 1,不同则结果为 0。进而统计异或的结果中 1 的个数,即为汉明距离。

方法一:内置位计数功能(来自官方题解)

大多数编程语言中,都存在各种内置计算等于 1 的位数函数。如果这是一个项目中的问题,应该直接使用内置函数,而不是重复造轮子。

代码如下:

class Solution {
    public int hammingDistance(int x, int y) {
        return Integer.bitCount(x ^ y); 
    }
}

方法二:移位

这里采用向右移位的方法,每次向右移动一位,这样每个位置都会被移到最右边,然后用 result & 1 == 1(与) 来检查最右边这一位是否为 1。

移位的话,由于是正整数,因此右移运算 (>>) 和无符号右移运算 (>>>) 都可以。

我的代码:

class Solution {
    public int hammingDistance(int x, int y) {
        int result = x ^ y;
        int distance = 0;
        for(int i = 0; i < 32; i++){
            if((result & 1) == 1){
                distance++;
            }
            result = result >> 1;
        }
        return distance;
    }
}

因为 int 型为 32 位,所以我用了 for 循环。应该用 while 循环更合适,如下。

官方题解:

class Solution {
    public int hammingDistance(int x, int y) {
    int xor = x ^ y;
    int distance = 0;
    while (xor != 0) {
        if (xor % 2 == 1)
	    distance += 1;
        xor = xor >> 1;
    }
    return distance;
    }
}

方法三:布莱恩-克尼根算法(来自官方题解)

方法二是逐位移动,逐位比较边缘位置是否为 1。寻找一种更快的方法找出等于 1 的位数。

上面例子中,遇到最右边的 1 后,如果可以跳过中间的 0,直接跳到下一个 1,效率会高很多。这就是布赖恩·克尼根位计数算法的基本思想。该算法使用特定比特位和算术运算移除等于 1 的最右比特位。当我们在 number 和 number-1 上做 AND 位运算时,原数字 number 的最右边等于 1 的比特会被移除,且最右边的 1 的左边各位保持不变。如下图:
在这里插入图片描述
代码如下:

class Solution {
    public int hammingDistance(int x, int y) {
        int xor = x ^ y;
        int distance = 0;
        while(xor != 0){
		distance += 1;
		xor = xor & (xor - 1);// 移除 xor 最右边的 1
	}
	return distance;
    }
}
发布了56 篇原创文章 · 获赞 0 · 访问量 933

猜你喜欢

转载自blog.csdn.net/weixin_45594025/article/details/104952294