只出现一次的数字
题目描述
给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。
示例 1 :
text
输入:nums = [2,2,1]
输出:1示例 2 :
text
输入:nums = [4,1,2,1,2]
输出:4示例 3 :
text
输入:nums = [1]
输出:1思路拆解
这道题如果使用哈希表,空间复杂度是 $O(n)$,不符合要求。题目要求 $O(1)$ 空间复杂度,这是 位运算 的经典应用场景。
异或运算 (XOR)
异或运算有以下性质:
- 任何数和 0 做异或运算,结果仍然是原来的数:
a ^ 0 = a。 - 任何数和其自身做异或运算,结果是 0:
a ^ a = 0。 - 异或运算满足交换律和结合律:
a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b。
算法流程
- 我们只需要把数组中所有的数字进行异或运算。
- 成对出现的数字会相互抵消(变成 0)。
- 最后剩下的就是那个只出现一次的数字。
代码实现
javascript
/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function(nums) {
let result = 0;
for (const num of nums) {
result ^= num;
}
return result;
};运行演示
假设 nums = [4, 1, 2, 1, 2]:
result = 0result ^ 4 = 4result ^ 1 = 4 ^ 1(二进制100 ^ 001 = 101= 5)result ^ 2 = 4 ^ 1 ^ 2result ^ 1 = 4 ^ 1 ^ 2 ^ 1 = 4 ^ (1 ^ 1) ^ 2 = 4 ^ 0 ^ 2 = 4 ^ 2result ^ 2 = 4 ^ 2 ^ 2 = 4 ^ (2 ^ 2) = 4 ^ 0 = 4
最终结果为 4。
复杂度分析
- 时间复杂度:$O(n)$,遍历一次数组。
- 空间复杂度:$O(1)$,只使用了常数个变量。
