简单题!!!我又可以了 首先是自己写的解法,可以达到时间100% 空间69%左右,后面两个是学习的大佬的解法。之前的每日一题用过一次树状数组,也简单了解了以下lowbit,但还是想不起来用,可能这就是我和大佬之间存在的差距吧。
思路–逐位比较
因为题目说最大不超过2的31次方,所以i
的上限为30,每次使用(x>>i)&1
来获取x
的当前位置是否为1
,逐位比较直接得到大答案。
时间复杂度O(C),C=31
因为要比较31
次。空间复杂度O(1)
。
代码1–自己写的,逐位比较 时间100% 内存消耗69.6%
class Solution {
public int hammingDistance(int x, int y)
{
int count = 0;
for(int i=30;i>=0;i--)
{
if((x>>i & 1) != (y>>i & 1))
count++;
}
return count;
}
}
思路—lowbit实现
lowbit(·)
函数一般出现在树状数组中,辅助获取二进制中等于1
的最低位,在这里起到同样的作用。
步骤:
- 先把
x
和y
进行异或操作,结果二进制编码中为1的位置就是x
和y
对应位置数字不同的位置,只要统计1
的个数就可以; - 反复调用
lowbit
函数,获取最低位为1
的位置,同时res++
时间复杂度O(C),C<=31
因为最多比较31
次。空间复杂度O(1)
。
代码2–借用树状数组内的lowbit实现 时间100% 内存消耗48.6%
class Solution {
public int lowBit(int x)
{
return x & (-x);
}
public int hammingDistance(int x, int y) {
int res = 0;
for(int i=x^y;i>0;i-=lowBit(i))
{
res++;
}
return res;
}
}
思路–移位运算
算法步骤:
- 先把
x
和y
进行或操作
,这样做的目的是尽可能的剪枝
——当两个数字的当前遍历位置左边所有位置均为0时,就停止遍历; - 然后把
x
和y
分别与1
进行与操作
,因为与操作
均为1才是1的性质,可以借此判断当前x
和y
的最低位是否为1,然后通过异或判断当前位置对应的数字是否相等; - 分别把
x
和y
向右移一位,从而下次可以比较新的位置;
该算法与第一个我写的思路都是逐位比较,但是这个算法在遍历数量上做了一定的剪枝
,但是操作却复杂了一些,两个方法各有利弊吧。
时间复杂度O(C),C<=31
因为最多比较31
次。空间复杂度O(1)
。
代码2–移位运算 时间100% 内存消耗5.6%
class Solution {
public int hammingDistance(int x, int y) {
int ans = 0;
while((x|y)!=0)
{
ans += (x&1) ^ (y&1);
x >>= 1;
y >>= 1;
}
return ans;
}
}