题目描述
思路解析动画文字版
思路一句话:每一位上 1 的个数对 3 取余,余几答案这一位就是几。出现三次的数贡献的 1 被 3 整除自动抵消。下面一步步演给你看。
开始前,先把数字翻成二进制。5 是 101,7 是 111,所以只有最低三位(第 0、1、2 位)需要统计。
现在专门数第 0 位。准备一个计数器 count = 0,指针从头扫到尾,凡这一位是 1 就 count 加一。
指针走到下标 0,nums[0] = 5,二进制 101。它的第 0 位是 1。是 1,count 要加一。
第 0 位是 1,count 加一变成 1(绿色标的都是这一位为 1 的数)。
指针走到下标 1,nums[1] = 5,二进制 101。它的第 0 位是 1。是 1,count 要加一。
第 0 位是 1,count 加一变成 2(绿色标的都是这一位为 1 的数)。
指针走到下标 2,nums[2] = 5,二进制 101。它的第 0 位是 1。是 1,count 要加一。
第 0 位是 1,count 加一变成 3(绿色标的都是这一位为 1 的数)。
指针走到下标 3,nums[3] = 7,二进制 111。它的第 0 位是 1。是 1,count 要加一。
第 0 位是 1,count 加一变成 4(绿色标的都是这一位为 1 的数)。
第 0 位数完,count = 4。对 3 取余得 1,所以答案在第 0 位上就是 1。出现三次的数贡献的 1 刚好被 3 整除抵消了。
现在专门数第 1 位。准备一个计数器 count = 0,指针从头扫到尾,凡这一位是 1 就 count 加一。
指针走到下标 0,nums[0] = 5,二进制 101。它的第 1 位是 0。是 0,count 不变,跳过。
指针走到下标 1,nums[1] = 5,二进制 101。它的第 1 位是 0。是 0,count 不变,跳过。
指针走到下标 2,nums[2] = 5,二进制 101。它的第 1 位是 0。是 0,count 不变,跳过。
指针走到下标 3,nums[3] = 7,二进制 111。它的第 1 位是 1。是 1,count 要加一。
第 1 位是 1,count 加一变成 1(绿色标的都是这一位为 1 的数)。
第 1 位数完,count = 1。对 3 取余得 1,所以答案在第 1 位上就是 1。出现三次的数贡献的 1 刚好被 3 整除抵消了。
现在专门数第 2 位。准备一个计数器 count = 0,指针从头扫到尾,凡这一位是 1 就 count 加一。
指针走到下标 0,nums[0] = 5,二进制 101。它的第 2 位是 1。是 1,count 要加一。
第 2 位是 1,count 加一变成 1(绿色标的都是这一位为 1 的数)。
指针走到下标 1,nums[1] = 5,二进制 101。它的第 2 位是 1。是 1,count 要加一。
第 2 位是 1,count 加一变成 2(绿色标的都是这一位为 1 的数)。
指针走到下标 2,nums[2] = 5,二进制 101。它的第 2 位是 1。是 1,count 要加一。
第 2 位是 1,count 加一变成 3(绿色标的都是这一位为 1 的数)。
指针走到下标 3,nums[3] = 7,二进制 111。它的第 2 位是 1。是 1,count 要加一。
第 2 位是 1,count 加一变成 4(绿色标的都是这一位为 1 的数)。
第 2 位数完,count = 4。对 3 取余得 1,所以答案在第 2 位上就是 1。出现三次的数贡献的 1 刚好被 3 整除抵消了。
把各位拼起来:第2位=1 第1位=1 第0位=1,二进制 111 就是十进制 7。那个只出现一次的数找到了。
三个高频追问:和 136 的区别、推广到出现 k 次、以及 ones/twos 状态机的进阶解法。
参考代码
def singleNumber(nums): ans = 0 for b in range(32): # 逐位统计 cnt = 0 for x in nums: cnt += (x >> b) & 1 # 这一位是不是 1 if cnt % 3: # 余 1 → 答案这一位为 1 ans |= 1 << b return ans - (1 << 32) if ans >= 1 << 31 else ans # 处理负数复杂度
- 时间:O(n),位数 32 是常数,对每一位扫一遍数组,总共 32×n 次,即线性
- 空间:O(1),只用 ans、count 几个整数变量,不开哈希表或额外数组
易错点
面试追问把动画讲成自己的话
追问和 136 题(只出现一次的数字 I)有什么区别?
追问如果其余元素出现 k 次(k 任意),怎么推广?
追问有没有 O(1) 空间但不用 32 次循环的位运算解法?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
数字范围按位与
LeetCode 201 · 中等 · 沿着 位运算套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题