本次讲解方法来自leetcode官方解答https://leetcode-cn.com/problems/single-number/solution/zhi-chu-xian-yi-ci-de-shu-zi-by-leetcode/
我们的最终目的使用线性复杂度,不是用额外空间做出来
方法一:
遍历全部情况
遍历 nums中的每一个元素
如果某个nums中的数字是新出现的,则将它添加到no_duplicate_list列表中
如果某个数字已经在列表中,删除它。
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
no_duplicate_list = []
for i in nums:
if i not in no_duplicate_list:
no_duplicate_list.append(i)
else:
no_duplicate_list.remove(i)
return no_duplicate_list.pop()
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
hash_table = {}
for i in nums:
try:
hash_table.pop(i)
#如果里面有i可以pop的话就pop出来
except:
hash_table[i] = 1
#没有i的话就往字典里加一个i的键值对
return hash_table.popitem()[0]
#popitem()这个函数是以list的形式返回字典中最后一个键值对,[0]就是取键的名字
方法三比较简单,用set是关键
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
return 2 * sum(set(nums)) - sum(nums)
最妙的是方法四
位操作
一个数的二进制是唯一的非零即一的组合
首先讲一下什么叫位运算,位运算就是对应位置的数字相同则为0,不同为1
如果两个相同的数做位运算,比如2和2
10 XOR 10 = 00
不同的两个数做位运算,比如2和3
10 XOR 11 = 01
然后再和2做位运算
01 XOR 10 = 11
我们发现它的结果就是3
这是因为相同的数字做位运算的结果是0,0和任何数做位运算就是那个数的本身,而且位运算有交换律,先和谁做位运算都不影响最后的结果。
所以我们用位运算可以在一次扫描的情况下使用O(1)的额外空间来做这道题
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
a = 0
for i in nums:
a ^= i
return a