Appearance
实战:只出现一次的数字 II
数组中其他元素都出现三次,只有一个出现一次,找出它。
问题描述
LeetCode 137. Single Number II
给你一个整数数组 nums,除某个元素仅出现一次外,其余每个元素都恰出现三次。找出那个只出现一次的元素。
要求:线性时间复杂度,常数空间。
示例:
输入:nums = [2,2,3,2]
输出:3思路
统计每一位上 1 出现的次数,如果是 3 的倍数,说明只出现一次的数在这一位是 0,否则是 1。
解法一:按位统计
javascript
function singleNumber(nums) {
let result = 0;
for (let i = 0; i < 32; i++) {
let count = 0;
const mask = 1 << i;
for (const num of nums) {
if (num & mask) count++;
}
if (count % 3 !== 0) {
result |= mask;
}
}
return result;
}执行过程
nums = [2, 2, 3, 2]
二进制:10, 10, 11, 10
位0:0+0+1+0 = 1,不是3的倍数,结果位0=1
位1:1+1+1+1 = 4,不是3的倍数,结果位1=1
结果:11 = 3解法二:状态机
用两个变量模拟"模 3 计数器":
javascript
function singleNumber(nums) {
let ones = 0, twos = 0;
for (const num of nums) {
ones = (ones ^ num) & ~twos;
twos = (twos ^ num) & ~ones;
}
return ones;
}这个方法更高效但较难理解。
状态机解释
ones:出现 1 次的位twos:出现 2 次的位- 出现 3 次时清零
状态转移:00 → 01 → 10 → 00
详细执行过程
以 nums = [2, 2, 3, 2] 为例,用按位统计法:
二进制表示:
2 = 10
2 = 10
3 = 11
2 = 10
位 0 的统计:0 + 0 + 1 + 0 = 1,1 % 3 = 1 ≠ 0,结果位 0 = 1
位 1 的统计:1 + 1 + 1 + 1 = 4,4 % 3 = 1 ≠ 0,结果位 1 = 1
结果:11 = 3状态机方法详解
用 (twos, ones) 表示每一位出现次数对 3 取模的状态:
状态转移(当前位为 1 时):
00 → 01(出现 1 次)
01 → 10(出现 2 次)
10 → 00(出现 3 次,清零)
状态转移(当前位为 0 时):
保持不变推导公式:
设输入位为 x,状态为 (twos, ones)
新 ones = (ones ^ x) & ~twos
新 twos = (twos ^ x) & ~ones边界情况
javascript
// 单个元素
singleNumber([5]); // 5
// 负数
singleNumber([-2, -2, -2, 3]); // 3
singleNumber([2, 2, 2, -3]); // -3
// 0 的情况
singleNumber([0, 0, 0, 5]); // 5常见错误
错误一:位数不够
javascript
// 错误:只统计了部分位
for (let i = 0; i < 16; i++) { ... }
// 正确:统计所有 32 位
for (let i = 0; i < 32; i++) { ... }错误二:处理负数时符号位问题
JavaScript 中位运算结果是 32 位有符号整数,需要注意:
javascript
// 如果最高位为 1,结果会是负数(这是正确的)
// 不需要特殊处理,按位统计自然支持负数通用化:其他元素出现 k 次
javascript
function singleNumber(nums, k) {
let result = 0;
for (let i = 0; i < 32; i++) {
let count = 0;
const mask = 1 << i;
for (const num of nums) {
if (num & mask) count++;
}
if (count % k !== 0) {
result |= mask;
}
}
return result;
}相关题目
| 题目 | 难度 | 关键点 |
|---|---|---|
| 137. 只出现一次的数字 II | 中等 | 本题 |
| 136. 只出现一次的数字 | 简单 | 其他出现 2 次 |
| 260. 只出现一次的数字 III | 中等 | 两个只出现 1 次 |
| 面试题 17.19. 消失的两个数字 | 困难 | 组合应用 |
总结
- 按位统计法:统计每位 1 的个数,模 3 判断
- 状态机法:用两个变量模拟模 3 计数器
- 通用思路:其他出现 k 次时,模 k 统计
- 时间空间:O(n) 时间,O(1) 空间
复杂度
- 时间:O(32n) = O(n)
- 空间:O(1)