题目描述
思路解析动画文字版
最直接的做法:把 x、y 都转成二进制字符串,补齐到一样长,再逐位比较,不同就加一。能做,但你的精力全花在“怎么补零、怎么对齐下标”上了。
关键一步:异或运算里,相同的位得 0、不同的位得 1。所以汉明距离,就等于 x 异或 y 之后结果里 1 的个数。补零这些杂事,异或一次全包了。
把两个数对齐成同宽:先把两个数放进同样的位宽里。x=1 看成 001,y=4 看成 100。下面要做的,就是给每一列算一次异或。
最高列:0 和 1 不同,异或得 1:看最高列:x 这位是 0,y 这位是 1,两位不同,异或得 1。这个 1 就代表一个差异位。
中间列:0 和 0 相同,异或得 0:中间列两个数都是 0,相同位异或得 0。这一列不算差异,不给答案贡献。
最低列:1 和 0 不同,异或得 1:最低列又不同,异或得 1。三列算完,z = 101。题目到这里已经被改写成:数 101 里有几个 1。
接下来用最经典的位扫描:每一轮只看 z 的最低位,是 1 就计数,然后把 z 右移一位丢掉这位。下面把这三轮慢镜头放给你看。
第 1 轮 · 看最低位:z 与 1 做与运算,只保留最低位。101 的最低位是 1,说明这里有个差异位,准备给 ans 加一。
第 1 轮 · ans 加 1:执行 ans 加上最低位,ans 从 0 变成 1。这一位已经数过,标记成处理完。
第 1 轮 · 右移,丢掉处理过的位:z 右移一位,刚数过的最低位被挤出去,整串往右滑,z 变成 10。最低位换成了新的一位,绝不会重复数。
第 2 轮 · 最低位是 0:现在最低位是 0,不是差异位。ans 加 0,仍然是 1。再右移:10 变成 1。
第 3 轮 · 最低位是 1,ans 再加 1:右移后只剩最后一个 1。最低位是 1,ans 再加一,变成 2。再右移,z 就被掏空了。
z 变成 0,循环结束,返回 ans:z 变成 0,while 条件不满足,循环停下。ans 记下的就是异或结果里 1 的总数,返回 2。和我们手数的答案一致。
这一题要记住的不是某个 API,而是这条翻译:看到“位不同”想异或,看到“数不同位”就数 1 的个数。
本题 x、y 非负不会踩,但同类题里 z 可能是负数。Java 的 z 右移如果用算术右移,最高位会一直补 1,z 永远不等于 0,死循环。所以习惯写无符号右移,三个尖括号,补 0 才安全。
面试追问:面试时把动画里的状态、为什么右移、有没有更快的写法,讲成自己的话,就稳了。
461 的后半段“数 z 里 1 的个数”,正是 191 位1的个数的全部。把它换成 Brian Kernighan 还能提速。想系统刷位运算,去 位运算专题,或直接做 191 位1的个数。不懂的随时问小欧。
边界三连:三种边界都验过:相等返回 0,一方为 0 退化成数另一方的 1,大数高位差异也照常统计。
参考代码
class Solution: def hammingDistance(self, x: int, y: int) -> int: z = x ^ y # 不同位变 1 ans = 0 while z: # 还有位没数完 ans += z & 1 # 最低位是 1 就计数 z >>= 1 # 右移,丢掉这位 return ans复杂度
- 时间复杂度:O(log C),C = max(x, y)。每右移一次处理一个二进制位,位数约 log C;固定 32 位整数时可视作 O(1)。
- 空间复杂度:O(1),全程只用 z、ans 两个整数变量,没有额外数组。
可套用的代码模板
这是可背的迁移骨架:凡是“数整数里 1 的个数”,都用 z 与 z 减 1 抹掉最低位的 1,循环几次就有几个 1。汉明距离只要先把 z 换成 x 异或 y。右上角可切 C++ / Java。
# 套路:要数整数 z 里 1 的个数?# 判据:z &= z - 1 每次抹掉最低位的一个 1def count_ones(z: int) -> int: ans = 0 while z: # 还有 1 没抹完 z &= z - 1 # 抹掉最低位的那个 1 ans += 1 # 抹一次 = 多一个 1 return ans# 汉明距离 = count_ones(x ^ y)易错点
面试追问把动画讲成自己的话
追问异或后的那些 1,含义是什么?
追问除了逐位右移,还有更快的写法吗?
追问复杂度怎么说?
追问如果不让用内置的 popcount / bin(z).count,能写吗?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。再去主线里挑下一道练手。
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题