AI刷题 找到单独的数 | 青训营笔记

81 阅读3分钟

AI刷题

问题描述

在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小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
  • 班级人数为奇数
  • 除了一个数字卡片只出现一次外,其余每个数字卡片都恰好出现两次

问题分析

给定一个整数数组 cards,其中只有一个整数是唯一的,其他整数都恰好出现两次。我们的目标是找出那个唯一的数字,并且要求时间复杂度为 O(n),同时尽量减少额外空间的使用。

分析要求

  • 时间复杂度 O(n) :意味着我们需要一次遍历或更少的操作来解决问题。
  • 减少额外空间:在题目中,最优的空间复杂度应为 O(1),即除了输入外不使用额外的数据结构。

解题思路

这个问题可以通过异或运算来高效地解决。

异或运算的特性

  1. a ^ a = 0:任何数字与其自身异或的结果为 0。
  2. a ^ 0 = a:任何数字与 0 异或的结果是数字本身。
  3. 异或运算满足交换律和结合律,即无论运算顺序如何,结果都是相同的。

解题步骤

  1. 初始时设定一个变量 result 为 0。
  2. 遍历数组中的每个数字,将其与 result 进行异或操作。由于每个数字恰好出现两次,所有出现两次的数字会相互抵消,最终只剩下那个唯一的数字。
  3. 最终 result 中存储的就是唯一的数字。

为什么这个方法可行?

  • 数组中的数字出现两次,异或运算后会抵消,留下的是那个只出现一次的数字。
  • 异或运算的时间复杂度为 O(1),因此遍历数组一次即可达到 O(n) 的时间复杂度。
  • 只需要一个额外的变量 result 来存储中间结果,因此空间复杂度为 O(1)。

代码实现

python
Copy code
def find_unique_card(cards):
    result = 0
    for card in cards:
        result ^= card  # 对所有元素进行异或操作
    return result

复杂度分析

  • 时间复杂度:O(n),我们只需要遍历数组一次。
  • 空间复杂度:O(1),只使用了一个额外的变量 result