题目
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:输入: [2,2,1];输出: 1
示例 2:输入: [4,1,2,1,2];输出: 4
解答一:
首先,如果我们不考虑额外空间的需求的话,这个问题可以有多种解法,比如使用列表操作,但是这种方法比较慢。这里介绍两种方法, 第一个是数学方法:
class Solution:
def singleNumber(self, nums):
num_set = list(set(nums))
s = sum(num_set)
return 2*s - sum(nums)
第二,我们还是用哈希表方法来做,找到只出现一次的数据,思路就是如果字典中出现了这个数字,就删除这个数字,最后只剩下了一个只出现一次的数字,然后使用popitem的方法把这个唯一的数字弹出来。
class Solution(object):
def singleNumber(self, nums):
hash_table = {}
for i in nums:
if i in hash_table:
hash_table.pop(i)
else:
hash_table[i] = 1
return hash_table.popitem()[0]
解答二
如果考虑不能使用额外空间的要求的话,我们可以使用异或运算的方法。异或运算满足三种性质:
- a^0 = a
- a^a = 0
- 异或运算满足交换律和结合律
我们可以这样想,先把出现了两次的相同数据放在最前面,他们进行异或运算就会得到0,最后的数据在与0做异或运算,就会得到唯一的数据本身。
class Solution:
def singleNumber(self, nums):
a = 0
for x in nums:
a = a ^ x
return a
最后放一下运行结果:
方法 | 消耗时间 | 消耗空间 |
---|---|---|
列表操作 | 1864ms | 16.4MB |
数学方法 | 248ms | 16.8MB |
哈希表(字典) | 204ms | 16.2MB |
异或方法 | 128ms | 16.2MB |