返回

揭秘 LeetCode 137:找到只出现一次的数字(出现三次的数字除外)

后端

LeetCode 137:只出现一次的数字 II

题目

给你一个整数数组 nums ,除某个元素仅出现 一次 外,其余每个元素都恰出现 三次 。请你找出并返回那个只出现 一次 的元素。

示例 1:

输入:nums = [2,2,3,2]
输出:3

示例 2:

输入:nums = [0,1,0,1,0,1,99]
输出:99

提示:

  • 1 <= nums.length <= 3 * 10^4
  • -2^31 <= nums[i] <= 2^31 - 1
  • 除某个元素仅出现一次外,其余每个元素都恰出现 三次

思路

为了找到只出现一次的数字,我们可以利用一个重要的数学性质:任何数字与其自身异或的结果为 0,即 x ^ x = 0。基于此,我们可以利用异或运算来抵消出现三次的数字,从而留下只出现一次的数字。

算法步骤

  1. 初始化 :设置两个变量 onestwos 为 0,分别表示数字出现一次和两次的异或结果。

  2. 遍历数组 :对于数组中的每个数字 num,执行以下步骤:

    • 如果 ones & num 为 0,则表示 num 出现一次。将 ones 更新为 ones ^ num
    • 如果 ones & num 不为 0,且 twos & num 为 0,则表示 num 出现两次。将 twos 更新为 twos ^ num
    • 如果 ones & num 不为 0,且 twos & num 也为 0,则表示 num 出现三次或以上。此时,不更新 onestwos
  3. 返回结果 :最后,返回 ones 的值,因为它包含了只出现一次的数字的异或结果。

代码实现

def singleNumber(nums):
  ones = 0
  twos = 0

  for num in nums:
    ones = (ones ^ num) & ~twos
    twos = (twos ^ num) & ~ones

  return ones

时间复杂度 :O(n),其中 n 是数组 nums 的长度。

空间复杂度 :O(1),因为只使用了几个变量。

示例代码

nums1 = [2, 2, 3, 2]
print(singleNumber(nums1))  # 输出:3

nums2 = [0, 1, 0, 1, 0, 1, 99]
print(singleNumber(nums2))  # 输出:99

总结

通过利用异或运算的性质,我们可以巧妙地找出只出现一次的数字,即使其他数字都出现了三次。LeetCode 137 是一道考察算法设计和数学技巧的经典题目,通过解决它,我们可以加深对数组操作和异或运算的理解。