问题简介
题目描述
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。
给你两个整数 x 和 y,计算并返回它们之间的汉明距离。
示例说明
✅ 示例 1:
输入:x = 1, y = 4
输出:2
解释:
1 (0 0 0 1)
4 (0 1 0 0)
↑ ↑
上面的箭头指出了对应二进制位不同的位置。
✅ 示例 2:
输入:x = 3, y = 1
输出:1
解题思路
💡 方法一:异或 + 逐位计数(推荐)
核心思想:
- 两个数异或(XOR)后,结果中为
1的位即为两数二进制表示不同的位置。 - 统计异或结果中
1的个数即可。
步骤:
- 计算
x ^ y得到差异位。 - 统计该结果中二进制
1的个数。- 可通过不断右移并检查最低位是否为
1实现。 - 或使用
n & (n - 1)技巧快速清除最低位的1。
- 可通过不断右移并检查最低位是否为
💡 方法二:内置函数(语言特性)
- Java:
Integer.bitCount(x ^ y) - Go:
bits.OnesCount(uint(x ^ y))
✅ 简洁高效,但需了解语言特性。
💡 方法三:逐位比较(不推荐,效率低)
- 分别取出
x和y的每一位进行比较。 - 需处理到最高有效位。
❌ 时间复杂度高,代码冗长。
代码实现
java
class Solution {
// 方法一:异或 + 逐位计数
public int hammingDistance(int x, int y) {
int xor = x ^ y;
int count = 0;
while (xor != 0) {
count += xor & 1; // 检查最低位是否为1
xor >>>= 1; // 无符号右移
}
return count;
}
// 方法一优化:使用 n & (n - 1) 清除最低位1
public int hammingDistanceOptimized(int x, int y) {
int xor = x ^ y;
int count = 0;
while (xor != 0) {
count++;
xor &= xor - 1; // 清除最低位的1
}
return count;
}
// 方法二:内置函数
public int hammingDistanceBuiltIn(int x, int y) {
return Integer.bitCount(x ^ y);
}
}
go
package main
import "math/bits"
func hammingDistance(x int, y int) int {
// 方法一:异或 + 逐位计数
xor := x ^ y
count := 0
for xor != 0 {
count += xor & 1
xor >>= 1
}
return count
}
// 方法一优化:使用 n & (n - 1)
func hammingDistanceOptimized(x int, y int) int {
xor := x ^ y
count := 0
for xor != 0 {
count++
xor &= xor - 1
}
return count
}
// 方法二:内置函数
func hammingDistanceBuiltIn(x int, y int) int {
return bits.OnesCount(uint(x ^ y))
}
示例演示
📌 以 x = 1, y = 4 为例:
| 步骤 | 操作 | 二进制表示 | 说明 |
|---|---|---|---|
| 1 | x ^ y |
0001 ^ 0100 = 0101 |
异或得到差异位 |
| 2 | 统计 0101 中 1 的个数 |
0101 → 2 个 1 |
汉明距离为 2 |
✅ 输出:2,符合预期。
答案有效性证明
- 正确性 :异或运算的性质保证了只有在两个位不同时结果为
1,因此统计1的数量即为不同位的数量。 - 边界情况 :
x == y→ 异或为0→ 距离为0✅x = 0,y = 2^31 - 1→ 所有位都不同 → 距离为31✅
- 数学依据 :汉明距离定义与异或结果中
1的数量完全等价。
复杂度分析
| 方法 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 异或 + 逐位右移 | O ( l o g m a x ( x , y ) ) O(\\log \\max(x, y)) O(logmax(x,y)) | O ( 1 ) O(1) O(1) | 最多 32 位 |
异或 + n & (n-1) |
O ( k ) O(k) O(k) | O ( 1 ) O(1) O(1) | k k k 为 1 的个数,最坏仍为 32 |
| 内置函数 | O ( 1 ) O(1) O(1)(硬件优化) | O ( 1 ) O(1) O(1) | 实际由 CPU 指令加速 |
💡 在实际应用中,
n & (n - 1)方法通常更快,因为跳过了0位。
问题总结
✅ 关键点回顾:
- 汉明距离 = 二进制不同位的数量。
- 异或 是解决此类"位差异"问题的核心操作。
- 统计二进制中
1的个数是常见子问题,掌握n & (n - 1)技巧非常有用。
📌 延伸思考:
- 若扩展到多个数,可考虑使用 Trie 或位运算批量处理。
- 在通信、编码理论中,汉明距离用于衡量纠错能力。
💡 一句话总结:
"异或找不同,数一得答案。"
github地址: https://github.com/swf2020/LeetCode-Hot100-Solutions