找单独的数 | 豆包MarsCode AI刷题

158 阅读3分钟

01161ff788e1334ca3f2d20c36f17f7d.jpg

题目速览

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。
现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
要求:
1.设计一个算法,使其时间复杂度为 O(n),其中 n是班级的人数。
2.尽量减少额外空间的使用,以体现你的算法优化能力。

解题思路

我们只需要进行一次循环,找到只出现一次的数即可。
假设,其余的数出现次数均大于一,只有一个数出现一次。这时我们只需要额外定义一个数组就可解决问题。
但题目希望尽量少使用额外空间,那应该怎么办呢?接下来介绍的位运算可以很好的解决问题。

位运算

基本运算符

符号描述运算规则应用场景
&两个位都为1时,结果才为1。常用于取数的某些特定位,如掩码操作,可通过与一个合适的掩码值进行按位与运算来提取或清除特定的位。
|两个位都为0时,结果才为0。常用于设置某些位的值,比如将某个数的特定位设为 1。
^异或两个位相同为0,相异为1。可用于在不使用临时变量的情况下交换两个数的值,也用于数据加密等领域中的简单加密算法,因为对同一个数进行两次相同的异或操作可以还原。
~取反0变1,1变0。
<<左移二进制位全部左移若干位,高位丢弃,低位补0。左移一位相当于乘以 2,左移 n 位相当于乘以 2 的 n 次方。可用于快速的乘法运算(对于 2 的幂次乘法)。
>>右移二进制位全部右移若干位,对无符号数,高位补0,有符号数,右移补1。右移一位相当于除以 2(对于无符号数或正数的算术右移情况),右移 n 位相当于除以 2 的 n 次方。

常用运算操作

  1. x 最右边的 n 位清零:x & (~0 << n)
  2. 获取 x 的第 n 位值(0 或者 1): (x >> n) & 1
  3. 获取 x 的第 n 位的幂值:x & (1 << (n -1))
  4. 仅将第 n 位置为 1x | (1 << n)
  5. 仅将第 n 位置为 0x & (~ (1 << n))
  6. x 最高位至第 n 位(含)清零:x & ((1 << n) - 1)
  7. 将第 n 位至第 0 位(含)清零:x & (~ ((1 << (n + 1)) - 1))

解题方案

题目让我们找出唯一出现的数,我们使用异或运算,相同的数字异或结果为0,从而得到唯一的不同数字。 异或运算原理如下:

  1. 任何数和 0 做异或运算,结果仍然是原来的数,即 a⊕0=a。
  2. 任何数和其自身做异或运算,结果是 0,即 a⊕a=0。
  3. 异或运算满足交换律和结合律,即 a⊕b⊕a=b⊕a⊕a=b⊕(a⊕a)=b⊕0=b 因此,本题解决。

总结

位运算是一种基于二进制的计算,运算速度很快,合理使用可以更好地解决问题。

推荐阅读

位运算全面总结,关于位运算看这篇就够了-CSDN博客
LeetCode从入门到超凡(五)深入浅出---位运算-CSDN博客