这道题是一个典型的“寻找唯一数字”的问题。我们需要寻找一个独特的数字,也就是一个只出现了一次,没有配对成功的数字。
这道题我一开始想到的是用字典来解决这个问题,代码如下:
def solution(inp):
num_count = {}
for num in inp:
if num in num_count:
num_count[num] += 1
else:
num_count[num] = 1
for num, count in num_count.items():
if count % 2 != 0:
return num
return 0
- 时间复杂度:O(n)
- 空间复杂度:O(n),因为在最坏情况下,所有数字都是唯一的,字典会存储 n 个元素。
我们先创建了一个空的字典 num_count,用来存储每个数字及其出现的次数。然后使用 for 对列表中的每个数字进行遍历,检查它是否已经在 num_count 字典中:
- 如果在字典中,说明这个数字已经出现过一次,因此将其计数加1。
- 如果不在字典中,说明这是第一次遇到这个数字,将其计数初始化为1。
接着通过遍历
num_count,检查每个数字的计数是否为奇数,如果为计数就返回这个数字,如果没有找到任何计数为奇数的数字,那么我们返回 0 就好了。
然后我就思考有没有第二种更加简单的方法,通过豆包MarsCode AI我找到了更加简单的解题方法,即通过使用异或运算来找到唯一的数字,代码如下:
def find_unique_number(inp):
result = 0
for num in inp:
result ^= num
return result
我觉得豆包MarsCode AI给出的方法非常的精妙,即可以利用异或运算的性质,所有成对出现的数字会相互抵消(因为 a ^ a = 0),最终 result 中只会剩下那个唯一出现一次的数字。
- 时间复杂度:O(n),因为只需遍历一次输入列表。
- 空间复杂度:O(1),因为只使用了一个额外的变量
result,不需要额外的存储空间。
异或运算的性质
异或运算具有以下几个重要性质:
-
自反性:任何数与自己异或的结果是0。
-
单位元:任何数与0异或的结果是它本身。
-
交换律:异或运算的顺序不影响结果。
-
结合律:异或运算的组合不影响结果。
所以我们先将 result 初始化为0。对列表进行遍历并且进行异或运算,在列表进行遍历结束后,result 的值就是唯一出现的数字,于是我们便轻而易举的使用异或运算解决这个问题了