《LeetCode刷题》—461.汉明距离
@[toc]
一、题目内容
原题连接:https://leetcode.cn/problems/hamming-distance/
题目:
二、个人答案(Java)
思路:题目的要求很容易理解,就给两个整数,转换成二进制之后,对应的位置不同的有几个,那么依次遍历再对比就行了,这里用的是一个for循环+一个判断语句,循环依次把两个整数转换为二进制0和1,然后判断是否相同,相同次数就+1,不相同就重新循环,每次循环都需要去重新除以2得到新的值,整个循环以数字大的那个数为标准,所以一开始三元运算符判断一下谁更大。
代码:
class Solution1 {
public int hammingDistance(int x, int y) {
int num=0;//记录次数
int temp=(x>y)?x:y;
for (int i = 0; temp!=0 ; i++) {
int x1=x%2,y1=y%2;
if (x1!=y1){
num++;
x=x/2;
y=y/2;
temp=temp/2;
}else {
x=x/2;
y=y/2;
temp=temp/2;
continue;
}
}
return num;
}
}
三、官方答案(Java)
方法一:内置位计数功能
思路:大多数编程语言都内置了计算二进制表达中 111 的数量的函数。在工程中,我们应该直接使用内置函数。
代码:
class Solution {
public int hammingDistance(int x, int y) {
return Integer.bitCount(x ^ y);
}
}
方法二:移位实现位计数
思路:在锻炼算法能力时,重复造轮子是不可避免的,也是应当的。因此读者们也需要尝试使用各种方法自己实现几个具有位计数功能的函数。本方法将使用位运算中移位的操作实现位计数功能。
具体地,记 s=x⊕ys = x \oplus ys=x⊕y,我们可以不断地检查 sss 的最低位,如果最低位为 111,那么令计数器加一,然后我们令 sss 整体右移一位,这样 sss 的最低位将被舍去,原本的次低位就变成了新的最低位。我们重复这个过程直到 s=0s=0s=0 为止。这样计数器中就累计了 sss 的二进制表示中 111 的数量。
代码:
class Solution {
public int hammingDistance(int x, int y) {
int s = x ^ y, ret = 0;
while (s != 0) {
ret += s & 1;
s >>= 1;
}
return ret;
}
}
方法三:Brian Kernighan 算法
思路:在方法二中,对于 s=(10001100)2s=(10001100)_2s=(10001100)2 的情况,我们需要循环右移 888 次才能得到答案。而实际上如果我们可以跳过两个 111 之间的 000,直接对 111 进行计数,那么就只需要循环 333 次即可。我们可以使用 Brian Kernighan 算法进行优化,具体地,该算法可以被描述为这样一个结论:记 f(x)f(x)f(x) 表示 xxx 和 x−1x-1x−1 进行与运算所得的结果(即 f(x)=x & (x−1)f(x)=x~\&~(x-1)f(x)=x & (x−1)),那么 f(x)f(x)f(x) 恰为 xxx 删去其二进制表示中最右侧的 111 的结果。
代码
class Solution {
public int hammingDistance(int x, int y) {
int s = x ^ y, ret = 0;
while (s != 0) {
s &= s - 1;
ret++;
}
return ret;
}
}
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/hamming-distance/solution/yi-ming-ju-chi-by-leetcode-solution-u1w7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。