Skip to content

只出现一次的数字

LeetCode 官方题目链接

题目描述

给你一个 非空 整数数组 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)

异或运算有以下性质:

  1. 任何数和 0 做异或运算,结果仍然是原来的数:a ^ 0 = a
  2. 任何数和其自身做异或运算,结果是 0:a ^ a = 0
  3. 异或运算满足交换律和结合律: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]

  1. result = 0
  2. result ^ 4 = 4
  3. result ^ 1 = 4 ^ 1 (二进制 100 ^ 001 = 101 = 5)
  4. result ^ 2 = 4 ^ 1 ^ 2
  5. result ^ 1 = 4 ^ 1 ^ 2 ^ 1 = 4 ^ (1 ^ 1) ^ 2 = 4 ^ 0 ^ 2 = 4 ^ 2
  6. result ^ 2 = 4 ^ 2 ^ 2 = 4 ^ (2 ^ 2) = 4 ^ 0 = 4

最终结果为 4。

复杂度分析

  • 时间复杂度:$O(n)$,遍历一次数组。
  • 空间复杂度:$O(1)$,只使用了常数个变量。

Power by VitePress