§1
题目描述
数组中只有一个数出现一次,其它都出现两次,找出那个数。
nums = [4,1,2,1,2]
输出 = 4
§2
思路解析动画文字版
关键不是背模板,而是看懂为什么这题适合位运算 · 异或。
1. 异或的两条性质:异或性质:x^x=0(相同抵消)、x^0=x。把所有数异或起来,成对的全消失,只剩出现一次的。ans 初始 0。
2. ^4 · ans=4:ans = 0 ^ 4 = 4。
3. ^1 · ans=5:ans = 4 ^ 1 = 5(暂时混进 1)。
4. ^2 · ans=7:ans = 5 ^ 2 = 7(再混进 2)。
5. 关键帧 · 第二个 1 抵消:关键帧:又遇到 1 → 两个 1 异或 = 0,自动抵消。ans 从 7 回到 6——别慌,看似变小其实是成对数字在互相消掉。
6. 第二个 2 抵消 · ans=4:又遇到 2 → 两个 2 也抵消。ans 回到 4。成对的都没了。
7. 答案 ans=4:扫完,剩下唯一没被抵消的 4 就是答案。和顺序无关,O(1) 空间。
把这句话记住,下次遇到同类题,就能更快选出方向。
迁移阶梯:把这题练到能复述后,再去同类题里迁移:先复用状态定义,再调整边界条件。
边界三连:边界三连:极端输入先过一遍。
几个高频追问,记住答法。
§3
参考代码
class Solution: def singleNumber(self, nums): ans = 0 for x in nums: ans ^= x return ans看懂代码不等于写得出。盖住上面,自己默写一遍试试。卡在哪一行说不清,就点右下角问小欧。
§4
复杂度
- 时间复杂度:O(n),一次遍历 n 个数,每个一次异或
- 空间复杂度:O(1),只用 1 个整型变量 ans
§5
可套用的代码模板
模板不是死背,而是提醒你写代码前先把状态、转移和边界排好。
# 位运算 · 异或 通用检查表# 1. 定义状态/指针/容器# 2. 每轮只做一个清晰动作# 3. 更新答案并处理边界§6
易错点
✗ 错误写法:用计数表也能做但多 O(n) 空间
✓ 正确写法:用异或让成对数字自动抵消
这题特意卡常数空间
✗ 错误写法:以为只对正数有效
✓ 正确写法:异或对负数(补码)同样成立
异或是逐位操作,与正负无关,含负数照样成对抵消。
✗ 错误写法:ans 初值设成 nums[0]
✓ 正确写法:初值设 0(异或单位元)
0^x=x,从 0 开始最干净;设别的值会污染结果。
§
面试追问把动画讲成自己的话
追问异或解法用了哪几条性质?
x^x=0(自反)、x^0=x(单位元)、交换结合律(任意配对)。全体异或后成对消失、剩唯一数。
追问若是「出现三次、一个一次」(LC137)?
异或不行,要按位统计每位 1 的个数 %3,或用两个变量模拟三进制状态机。
追问复杂度?
O(n) 一次遍历、O(1) 空间。
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
下一题 · 位运算 2/8
→位 1 的个数
LeetCode 191 · 简单 · 沿着 位运算 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
299道动画图解
37节语音讲解
28课数据结构
¥0.27折合 / 天
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
¥99 开通年卡 →
想成体系刷透这类套路?去图解算法专题