简单LeetCode 136动画补充中引导学习
只出现一次的数字
位运算:异或消消乐
把数组里所有的数异或起来:成对的数异或为 0,任何数和 0 异或等于它自己——最后剩下的就是答案。
时间复杂度 O(n)空间复杂度 O(1)
题单:面试热题
题目描述
给定一个整数数组,其中除了某个元素只出现一次外,其余元素都恰好出现两次,找出这个只出现一次的元素。要求线性时间、常数空间。
学习目标
能解释异或的三条性质,并说清为什么成对元素会抵消、只出现一次的元素会留下。
已完成 0 / 6 阶段
诊断
先问:为什么不能用哈希表
用哈希表统计每个数出现次数,最后找次数为 1 的数,正确吗?题目要求 O(1) 空间,问题在哪?
建议先完成当前阶段(提示 / 检查 / 自评),再进入下一步;也可以直接跳过。
解题思路
核心思想
把数组里所有的数异或起来:成对的数异或为 0,任何数和 0 异或等于它自己——最后剩下的就是答案。
为什么需要它
要求 O(1) 空间就排除了哈希计数;"成对出现"的特性提示需要一种能"自己抵消"的运算。
第一反应:直觉方案
哈希表统计每个数出现的次数,最后找出次数为 1 的那个。能过,但要多花 O(n) 空间。
关键洞察
关键洞察是异或的三条性质:x ^ x = 0(自消)、x ^ 0 = x(保底)、满足交换律和结合律(顺序无关)。正因为顺序无关,成对的元素无论在哪里都会两两抵消。以后遇到"配对 / 抵消 / 找唯一"的题,先想异或。
时间复杂度 O(n)空间复杂度 O(1)
易错点
- 初始值用 0(0 ^ x = x),不要用第一个元素起步再特判
- 异或满足交换律——不需要先排序,也不需要处理顺序问题
- 注意前提:恰好一个元素出现一次、其余都出现两次;前提变了这个技巧就不成立
参考代码
参考代码
1function singleNumber(nums) {
2 let result = 0;
3 for (const x of nums) {
4 result ^= x;
5 }
6 return result;
7}
逐步演示
这道题目前是索引版:题面、解题思路与双语言代码已是完整内容; 逐步动画会按计划补充。