题目描述
思路解析动画文字版
两把钥匙:xorAll = 全体异或 = a^b;diff = xorAll 最低位的 1,用它把 a 和 b 分到两组里各自捞出来。下面一帧帧演。
第一趟开始。准备一个累加器 xorAll = 0,从左到右把每个数异或进去。
指针走到下标 0,这一格是 1。把它异或进 xorAll(当前 xorAll = 0)。
异或完成:xorAll 从 0 变成 1。下标 0 及之前的数都已处理(标蓝)。
指针走到下标 1,这一格是 2。把它异或进 xorAll(当前 xorAll = 1)。
异或完成:xorAll 从 1 变成 3。下标 1 及之前的数都已处理(标蓝)。
指针走到下标 2,这一格是 1。把它异或进 xorAll(当前 xorAll = 3)。
异或完成:xorAll 从 3 变成 2。下标 2 及之前的数都已处理(标蓝)。
指针走到下标 3,这一格是 3。把它异或进 xorAll(当前 xorAll = 2)。
异或完成:xorAll 从 2 变成 1。下标 3 及之前的数都已处理(标蓝)。
指针走到下标 4,这一格是 2。把它异或进 xorAll(当前 xorAll = 1)。
异或完成:xorAll 从 1 变成 3。下标 4 及之前的数都已处理(标蓝)。
指针走到下标 5,这一格是 5。把它异或进 xorAll(当前 xorAll = 3)。
异或完成:xorAll 从 3 变成 6。下标 5 及之前的数都已处理(标蓝)。
第一趟结束。所有成对的数互相抵消,xorAll = 6,它正好等于两个落单数 a 与 b 的异或值。
取 xorAll 最低位的那个 1:diff = xorAll &(-xorAll) = 2。a 和 b 在这一位上一定不同,用它把它们分到两组。
第二趟开始。两个累加器 a=0、b=0。按「这个数和 diff 与一下是不是 0」把每个数分进 A 组或 B 组。
指针到下标 0,值 1。1 和 diff(2) 与一下得 0,为 0,分到 B 组。
B 组(红):b 从 0 异或 1 变成 1。每组里成对的数还是会抵消。
指针到下标 1,值 2。2 和 diff(2) 与一下得 2,不为 0,分到 A 组。
A 组(绿):a 从 0 异或 2 变成 2。每组里成对的数还是会抵消。
指针到下标 2,值 1。1 和 diff(2) 与一下得 0,为 0,分到 B 组。
B 组(红):b 从 1 异或 1 变成 0。每组里成对的数还是会抵消。
指针到下标 3,值 3。3 和 diff(2) 与一下得 2,不为 0,分到 A 组。
A 组(绿):a 从 2 异或 3 变成 1。每组里成对的数还是会抵消。
指针到下标 4,值 2。2 和 diff(2) 与一下得 2,不为 0,分到 A 组。
A 组(绿):a 从 1 异或 2 变成 3。每组里成对的数还是会抵消。
指针到下标 5,值 5。5 和 diff(2) 与一下得 0,为 0,分到 B 组。
B 组(红):b 从 0 异或 5 变成 5。每组里成对的数还是会抵消。
两趟扫完。A 组异或剩下 a=3,B 组异或剩下 b=5,这两个就是只出现一次的数:[3, 5]。
三个高频追问:diff 的含义、a/b 为何分到不同组、以及与单个落单数版本的关系。
参考代码
def singleNumber(nums): xor_all = 0 for x in nums: # 第一趟:全体异或 xor_all ^= x # 成对抵消,剩 a^b diff = xor_all & (-xor_all) # 取最低的 1 位 a = b = 0 for x in nums: # 第二趟:按 diff 位分组 if x & diff: a ^= x # A 组 else: b ^= x # B 组 return [a, b]复杂度
- 时间:O(n),两趟线性扫描,每个元素各看常数次
- 空间:O(1),只用 xorAll、diff、a、b 几个整数,不开额外数组
易错点
面试追问把动画讲成自己的话
追问diff = xorAll &(-xorAll) 在做什么?
追问为什么两个落单数一定落在不同组?
追问如果题目改成只有一个数出现一次呢?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最大单词长度乘积
LeetCode 318 · 中等 · 沿着 位运算套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题