要解决这个问题,关键是要找到那个只出现一次的数字。由于题目要求时间复杂度为 O(n) 且尽量减少额外空间的使用,我们可以利用异或运算来达到这个目标。
异或运算的特性:
- a ^ a = 0:任何一个数字与自身异或的结果是 0。
- a ^ 0 = a:任何数字与 0 异或的结果是数字本身。
- 异或运算满足交换律和结合律:即顺序不影响结果。
根据这些特性,我们可以遍历所有卡片上的数字,并对它们进行异或运算。由于所有的数字除了一个外都出现了两次,两个相同的数字会相互抵消(变为 0),最终留下的就是那个唯一出现一次的数字。
解题思路:
- 遍历所有卡片上的数字,使用一个变量来保存当前的异或结果。
- 由于异或运算的特性,所有成对出现的数字会被抵消,最终剩下的就是那个唯一的数字。
代码实现:
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)
解释:
- 时间复杂度:每次遍历卡片数组,操作是 O(1),因此总的时间复杂度是 O(n),其中 n 是卡片的数量。
- 空间复杂度:我们只使用了一个变量
unique_number来保存中间结果,因此空间复杂度是 O(1)。
测试用例:
- 输入
[1, 1, 2, 2, 3, 3, 4, 5, 5],输出4,因为除了4外,其他数字都成对出现。 - 输入
[0, 1, 0, 1, 2],输出2,因为2是唯一没有配对的数字。 - 输入
[7, 3, 3, 7, 10],输出10,因为10是唯一没有配对的数字。
通过这种方式,我们能够在 O(n) 时间复杂度内解决问题,且只使用常量空间。