返回

只出现一次的数字:掌握“位运算”巧解 LeetCode 136

前端

引言

在编程世界中,LeetCode 是一座算法题目的宝库,吸引着无数开发者前来挑战。其中,第 136 号题目“只出现一次的数字”备受青睐,它考验着我们对位运算的掌握程度。位运算是一种在计算机科学中广泛应用的技巧,它能够巧妙地处理二进制数据,带来意想不到的算法效率提升。今天,我们就来探索位运算的奥秘,一起破解 LeetCode 136 的难题!

题目剖析

LeetCode 136 的题目如下:

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出只出现一次的那个元素。

乍一看,题目似乎有些棘手,但只要我们深入理解题目要求,就能发现解决它的关键就在于找出数组中那个“独行侠”元素。我们可以利用位运算中独具特色的“异或运算(XOR)”来巧妙地完成这个任务。

异或运算的奥秘

异或运算(XOR)是位运算中的明星操作符,它用符号“^”表示。异或运算的规则非常简单,当两个二进制位相同(都为 0 或都为 1)时,异或运算结果为 0;当两个二进制位不同(一个为 0,另一个为 1)时,异或运算结果为 1。

异或运算的一个神奇之处在于,当一个数与自身进行异或运算时,结果总是 0。此外,当一个数与 0 进行异或运算时,结果仍然是它本身。基于这两个特性,我们可以构建出解决 LeetCode 136 问题的算法。

算法详解

步骤 1:初始化

我们将使用一个变量 result 来存储最终结果,并将其初始化为 0。

步骤 2:循环遍历数组

我们对给定的整数数组进行遍历,对于数组中的每个元素 nums[i],我们执行以下操作:

result ^= nums[i];

步骤 3:返回结果

遍历完成后,result 中存储的就是只出现一次的数字。

算法原理

通过对数组中的每个元素进行异或运算,我们巧妙地利用了异或运算的特性:

  • 当一个数出现两次时,它与自身异或会得到 0,从而抵消掉之前存储在 result 中的结果。
  • 当一个数只出现一次时,它与 result 异或会保留它本身的值。

经过遍历,result 中剩余的数字就是只出现一次的那个元素。

代码实现

def single_number(nums):
  """
  :type nums: List[int]
  :rtype: int
  """
  result = 0
  for num in nums:
    result ^= num
  return result

复杂度分析

  • 时间复杂度:O(n),其中 n 为数组 nums 的长度。
  • 空间复杂度:O(1),因为我们只使用了常数空间来存储 result。

总结

通过对位运算,尤其是异或运算的深入理解,我们成功破解了 LeetCode 136 难题。位运算在计算机科学中扮演着至关重要的角色,掌握它能够为我们解决各种算法问题带来事半功倍的效果。

进阶探索

  • 扩展算法:如果数组中出现多次的元素不止一个,如何找出它们?
  • 异或运算的应用:位运算还可以应用在其他编程领域,比如数据加密、集合操作和错误检测。
  • 算法优化:是否存在更优化的算法来解决 LeetCode 136 问题?