力扣-461-汉明距离
汉明距离是指:两个二进制数,不同位的个数
啊,我又想到了十进制转二进制的算法,我没写过,现在都还在我的草稿箱里
好,会写十进制转二进制了,现在我获得了保存了各位的两个栈
需要考虑的首要问题便成了如何解决位数不一致的问题,如果我想要比较他俩是否一致的话
我突然有个想法,为什么要转换完再比较呢?边转变比不是更好?
但是如果采用我这种思路的话,就很难边转换边比,因为有一步取逆操作,导致对齐方式不一样
题解
GCC内置函数__builtin_popcount
在工程中建议直接使用库函数
用来返回二进制中1的个数
// 代码就一行
return __builtin_popcount(x ^ y);
又遇到了位运算,x^y
什么意思呢?
即是二进制数中位值不同的会被标记为1,然后只要用内置函数统计1的个数就可以了
啊,学了位运算又搞忘了
移位运算实现统计1的个数
有了x^y
,问题一下子就转换了,变成了统计二进制1的个数问题
官方推荐的是移位运算,我们都知道移位运算效率很高
class Solution {
public:
int hammingDistance(int x, int y) {
int s = x^y,ret = 0;
while(s){
ret+=s&1;
// 和1做与运算,即最后一位与1做与运算,可以判断是不是1
s >>= 1;
// 右移一位
}
return ret;
}
};
效率很高
是不是涉及二进制都该想到位运算的
Brian Kernighan 算法
x&(x-1)==x的二进制表示中减去最右边的1
思路仍然是统计1的个数,不过却要进一步提高效率
int hammingDistance(int x, int y) {
int s = x^y,ret = 0;
while(s){
s&=(s-1);
// 这一步相当于去掉x二进制表示中最右边的1
ret++;
}
return ret;
}
像比与第二种解法,这一种解法就相当于只统计1,不统计0了,减少了循环次数
理论上……但实际好像并没有
这个技巧之前做得那道位运算题也见力扣官方用过的
哈哈哈,回头看了眼,要做的不就是那一道题吗,统计二进制1的个数
居然想到😂