题目
两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。
给出两个整数 x 和 y,计算它们之间的汉明距离。
注意:
0 ≤ x, y < 2^31.
示例:
输入: x = 1, y = 4
输出: 2
解释:
上面的箭头指出了对应二进制位不同的位置。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/hamming-distance
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
对应二进制位不同的位置的数目
也就是经过位运算中的异或运算,结果包含“1”的数目
提交代码
异或运算结果十进制转二进制,计算字符串中“1”的次数
class Solution:
def hammingDistance(self, x: int, y: int) -> int:
return bin(x^y).count('1')
- 时间复杂度O(1)
一个为XOR异或操作,一个为字符串内置函数,前者是固定时间,后者最坏情况是O(k),其中 k 是整数的位数。
- 空间复杂度O(1)
使用恒定大小的空间保存 XOR 的结果,并假设内置函数也使用恒定空间。
优化改进
移位
逻辑移位,对于题目中要求的32位数字,异或操作后一般而言高位0较多,低位1较多,于是采取逻辑右移,判断最右边的数字是否为1,通过 (&)与运算 或取模运算(i % 2)(这两个操作都会屏蔽最右位以外的其他位),并移入 0 进行左侧的补位。
- 代码
class Solution:
def hammingDistance(self, x: int, y: int) -> int:
z = x ^ y
count = 0
while z :
if z & 1:
count += 1
z = z >> 1
return count
- 时间复杂度O(1)
Integer 的大小固定,处理时间也固定。32 位整数需要 32 次迭代。
- 空间复杂度O(1)
使用恒定大小的空间。
布赖恩·克尼根算法
关键点
与逻辑移位不同的是,该计数算法的基本思想在于遇到最右边的“1”之后,跳过和下一个“1”位置之间的“0”,提高效率。
- 实现方式
针对含有“1”的特定比特位,利用算术运算减去 1 ,再通过二者做&与运算消除“1”。
class Solution:
def hammingDistance(self, x: int, y: int) -> int:
z = x ^ y
count = 0
while z :
count += 1
z = z & (z - 1)
return count
迭代次数减少
:每次运算都会移除一个“1”
- 时间复杂度O(1)
Integer 的大小固定,处理时间也固定。32 位整数需要 32 次迭代。
- 空间复杂度O(1)
与输入无关,使用恒定大小的空间。
学习总结
- 逻辑移位的python代码表达;
- 对于简单位运算,时间复杂度跟整数位数有关,为常数,故时间复杂度为O(1);
- 布赖恩·克尼根计数算法的使用。