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

108 阅读3分钟

1. 找单独的数题目解析

题目关键点

  1. 班级中有 n 个学生,手中分别持有一个数字卡片。
  2. 除一个数字外,其余数字均出现两次。
  3. 我们需要在 O(n) 时间复杂度下,找出唯一的、不成对的数字。
  4. 额外空间尽量少,用异或操作是最佳选择。

思路解析

异或的特性

  1. 相同数字异或结果为 0: x⊕x=0
  2. 任意数字与 0 异或结果为自身: x⊕0=x
  3. 异或运算满足交换律和结合律: a⊕b⊕c=c⊕a⊕b

因此,多个数字异或后,顺序无关。

算法核心

  • 利用异或操作将所有数字进行逐一累积。
  • 重复出现的数字会因 x⊕x=0抵消。
  • 最终结果就是唯一出现一次的数字。

代码详解

以下是代码及其步骤:

def solution(cards):
    unique = 0  # 初始异或值设为0
    for card in cards:  # 遍历所有卡片
        unique ^= card  # 将当前卡片数字与累积值进行异或
    return unique  # 最终累积值即为唯一数字

代码解析

  1. 初始值: 定义变量 unique = 0,表示当前的异或累积结果。

  2. 逐步异或: 遍历列表中的每个数字 card,将其与 unique 进行异或运算。

    • 如果数字出现两次,则其异或结果变为 0,对最终结果没有影响。
    • 唯一出现一次的数字始终保留在 unique 中。
  3. 返回结果: 遍历结束后,unique 即为最终答案。


图解过程

假设输入 cards = [1, 1, 2, 2, 3, 3, 4, 5, 5]

步骤当前卡片 (card)累积值 (unique)说明
初始值-0初始化为 0
第一步10⊕1=1第一个 1
第二步11⊕1=0第二个 1 抵消
第三步20⊕2=2第一个 2
第四步22⊕2=0第二个 2 抵消
第五步30⊕3=3第一个 3
第六步33⊕3=0第二个 3 抵消
第七步40⊕4=4唯一数字 4
第八步54⊕5=1第一个 5
第九步51⊕5=4第二个 5 抵消
结果-4唯一数字

测试样例

测试代码如下:

if __name__ == "__main__":
    # 测试样例1
    print(solution([1, 1, 2, 2, 3, 3, 4, 5, 5]) == 4)  # True
    # 测试样例2
    print(solution([0, 1, 0, 1, 2]) == 2)  # True
    # 测试样例3
    print(solution([7, 3, 3, 7, 10]) == 10)  # True

样例结果

  1. 输入 [1, 1, 2, 2, 3, 3, 4, 5, 5],输出 4
  2. 输入 [0, 1, 0, 1, 2],输出 2
  3. 输入 [7, 3, 3, 7, 10],输出 10

复杂度分析

时间复杂度

  • 遍历列表一次,时间复杂度为 O(n)。

空间复杂度

  • 只使用了一个变量 unique,空间复杂度为 O(1)。

两个常数的异或值计算

两个常数的异或值可以通过按位异或运算来计算。异或运算(XOR)是对二进制位进行操作的逻辑运算,规则如下:

  • 如果对应位的数字相同,则结果为 0。
  • 如果对应位的数字不同,则结果为 1。

例如,计算 5⊕3:

  1. 将数字转为二进制

    • 5 的二进制表示为 0101
    • 3 的二进制表示为 0011
  2. 按位异或

    • 0⊕0=0
    • 1⊕0=1
    • 0⊕1=1
    • 1⊕1=0

    结果是 0110

  3. 将结果转回十进制: 0110 的十进制是 6。

因此,5⊕3=6

代码示例

在 Python 中,可以使用 ^ 运算符计算异或:

a = 5
b = 3
result = a ^ b
print(result)  # 输出 6

这种按位异或适用于任何两个整数,计算过程相同。