AI刷题丨找单独的数

99 阅读4分钟
### 问题描述

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。

要求:

  1. 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
  2. 尽量减少额外空间的使用,以体现你的算法优化能力。

测试样例

样例1:

输入:cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]
输出:4
解释:拿到数字 4 的同学是唯一一个没有配对的。

样例2:

输入:cards = [0, 1, 0, 1, 2]
输出:2
解释:数字 2 只出现一次,是独特的卡片。

样例3:

输入:cards = [7, 3, 3, 7, 10]
输出:10
解释:10 是班级中唯一一个不重复的数字卡片。

约束条件

  • 1 ≤ cards.length ≤ 1001
  • 0 ≤ cards[i] ≤ 1000
  • 班级人数为奇数
  • 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次
第一次我想到用哈希表写,于是写了以下的代码:
    count = {}
    for card in cards:
        if card in count:
            count[card] += 1
        else:
            count[card] = 1
    for card, cnt in count.items():
        if cnt == 1:
            return card

使用一个哈希表(或字典)来记录每个数字出现的次数。遍历数组,对于每个数字,如果它在哈希表中已经存在,则将其计数加1,否则添加到哈希表中并设置计数为1。最后,遍历哈希表,找到计数为1的数字。 时间复杂度满足O(n)但是题目要求尽量减少额外空间的使用,以体现你的算法优化能力。
所以我想了以下的方法来优化额外空间的使用:

    result = 0
    for number in numbers:
        result ^= number
    return result

input_example_1 = "1 1 2 2 3 3 4 5 5"

input_example_2 = "0 1 0 1 2"

numbers_1 = list(map(int, input_example_1.split()))
numbers_2 = list(map(int, input_example_2.split()))

print(solution(numbers_1)) 
print(solution(numbers_2))  

代码定义了一个名为 solution 的函数,它接受一个整数列表 numbers 作为参数,并返回一个整数 result,这个整数是列表中只出现一次的那个数字。

函数的工作原理是利用异或运算的性质:任何数与自身异或结果为0,任何数与0异或结果为它本身。因此,如果列表中的所有数字都成对出现,它们两两异或的结果将是0。而只出现一次的数字与0异或就是它本身,所以最终的 result 就是那个只出现一次的数字。
异或(XOR)操作是一种位运算,具有以下性质:

  1. 交换律:𝐴⊕𝐵=𝐵⊕𝐴A⊕B=B⊕A

    • 异或运算满足交换律,即两个数进行异或操作的顺序可以交换。
  2. 结合律:(𝐴⊕𝐵)⊕𝐶=𝐴⊕(𝐵⊕𝐶)(A⊕B)⊕C=A⊕(B⊕C)

    • 异或运算满足结合律,即三个或三个以上的数进行异或操作时,可以任意分组。
  3. 恒等元素:𝐴⊕0=𝐴A⊕0=A

    • 任何数与0进行异或操作,结果仍然是原数。
  4. 逆元素:𝐴⊕𝐴=0A⊕A=0

    • 任何数与其自身进行异或操作,结果为0。
  5. 对加法的分配律:𝐴⊕(𝐵+𝐶)=(𝐴⊕𝐵)+(𝐴⊕𝐶)A⊕(B+C)=(A⊕B)+(A⊕C)

    • 异或运算对加法运算满足分配律。
  6. 对减法的分配律:𝐴⊕(𝐵−𝐶)=(𝐴⊕𝐵)−(𝐴⊕𝐶)A⊕(B−C)=(A⊕B)−(A⊕C)

    • 异或运算对减法运算也满足分配律。
  7. 对乘法的分配律:𝐴⊕(𝐵×𝐶)=(𝐴⊕𝐵)×(𝐴⊕𝐶)A⊕(B×C)=(A⊕B)×(A⊕C)

    • 异或运算对乘法运算满足分配律。
  8. 对除法的分配律:𝐴⊕(𝐵/𝐶)=(𝐴⊕𝐵)/(𝐴⊕𝐶)A⊕(B/C)=(A⊕B)/(A⊕C)

    • 异或运算对除法运算满足分配律。
  9. 对幂运算的分配律:𝐴⊕(𝐵𝐶)=(𝐴⊕𝐵)𝐶A⊕(BC)=(A⊕B)C

    • 异或运算对幂运算满足分配律。
  10. 对取模运算的分配律:𝐴⊕(𝐵%𝐶)=(𝐴⊕𝐵)%(𝐴⊕𝐶)A⊕(B%C)=(A⊕B)%(A⊕C)

    • 异或运算对取模运算满足分配律。
  11. 对逻辑与运算的分配律:𝐴⊕(𝐵&𝐶)=(𝐴⊕𝐵)&(𝐴⊕𝐶)A⊕(B&C)=(A⊕B)&(A⊕C)

    • 异或运算对逻辑与运算满足分配律。
  12. 对逻辑或运算的分配律:𝐴⊕(𝐵∣𝐶)=(𝐴⊕𝐵)∣(𝐴⊕𝐶)A⊕(B∣C)=(A⊕B)∣(A⊕C)

    • 异或运算对逻辑或运算满足分配律。
  13. 对逻辑非运算的恒等性:¬(𝐴⊕𝐵)=¬𝐴⊕¬𝐵¬(A⊕B)=¬A⊕¬B

    • 异或运算对逻辑非运算满足恒等性。