题目简述
在一个班级中,每位同学都拿到了一张卡片,上面有一个整数。有趣的是,除了一个数字之外,所有的数字都恰好出现了两次。现在需要你帮助班长小C快速找到那个拿了独特数字卡片的同学手上的数字是什么。
要求:
- 设计一个算法,使其时间复杂度为 O(n),其中 n 是班级的人数。
- 尽量减少额外空间的使用,以体现你的算法优化能力。
解题方法
解题思想
可以通过使用位运算中的异或(XOR)操作来高效解决。异或操作具有以下性质:
- 任何数与0进行异或操作,结果仍然是这个数本身:
a ^ 0 = a - 任何数与自身进行异或操作,结果为0:
a ^ a = 0 - 异或操作满足交换律和结合律:
a ^ b ^ a = (a ^ a) ^ b = 0 ^ b = b
基于这些性质,如果我们将所有数字进行异或操作,那么成对出现的数字将会互相抵消(因为 a ^ a = 0),而只出现一次的那个数字将会保留下来(因为它没有另一个相同的数字与其相异或以抵消)。因此,最终的结果就是那个独一无二的数字。
算法步骤
- 初始化一个变量
unique为0。 - 遍历班级中每位同学手中的卡片上的整数,将每个整数与
unique进行异或操作,并更新unique的值。 - 遍历结束后,
unique就是那个唯一的数字。
Python 实现示例
def solution(cards):
unique = 0
for num in cards:
unique ^= num
return unique
分析
- 时间复杂度:该算法的时间复杂度为 O(n),其中 n 是数组的长度。这是因为我们需要遍历整个数组一次。
- 空间复杂度:该算法的空间复杂度为 O(1),因为我们只使用了一个额外的变量
unique来存储中间结果,不需要依赖于输入大小的额外数据结构。
其他解题思路
使用哈希表(Hash Table)
这种方法通过记录每个数字出现的次数来解决问题。遍历数组时,对于每个数字,在哈希表中增加其计数;最后再遍历哈希表,找到计数为1的那个数字。
Python 示例代码:
def solution(cards):
count = {}
for num in cards:
if num in count:
count[num] += 1
else:
count[num] = 1
for key, value in count.items():
if value == 1:
return key
- 时间复杂度:O(n),其中 n 是数组长度。
- 空间复杂度:O(n),最坏情况下需要存储所有元素。