寻找独特数字卡片|青训营笔记

44 阅读2分钟

要解决这个问题,关键是要找到那个只出现一次的数字。由于题目要求时间复杂度为 O(n) 且尽量减少额外空间的使用,我们可以利用异或运算来达到这个目标。

异或运算的特性:

  1. a ^ a = 0:任何一个数字与自身异或的结果是 0。
  2. a ^ 0 = a:任何数字与 0 异或的结果是数字本身。
  3. 异或运算满足交换律和结合律:即顺序不影响结果。

根据这些特性,我们可以遍历所有卡片上的数字,并对它们进行异或运算。由于所有的数字除了一个外都出现了两次,两个相同的数字会相互抵消(变为 0),最终留下的就是那个唯一出现一次的数字。

解题思路:

  1. 遍历所有卡片上的数字,使用一个变量来保存当前的异或结果。
  2. 由于异或运算的特性,所有成对出现的数字会被抵消,最终剩下的就是那个唯一的数字。

代码实现:

def solution(cards):
    unique_number = 0
    for card in cards:
        unique_number ^= card  # 对每个数字进行异或操作
    return unique_number  # 最终返回异或结果,即唯一的数字

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

解释:

  1. 时间复杂度:每次遍历卡片数组,操作是 O(1),因此总的时间复杂度是 O(n),其中 n 是卡片的数量。
  2. 空间复杂度:我们只使用了一个变量 unique_number 来保存中间结果,因此空间复杂度是 O(1)。

测试用例:

  1. 输入 [1, 1, 2, 2, 3, 3, 4, 5, 5],输出 4,因为除了 4 外,其他数字都成对出现。
  2. 输入 [0, 1, 0, 1, 2],输出 2,因为 2 是唯一没有配对的数字。
  3. 输入 [7, 3, 3, 7, 10],输出 10,因为 10 是唯一没有配对的数字。

通过这种方式,我们能够在 O(n) 时间复杂度内解决问题,且只使用常量空间。