链接:https://leetcode-cn.com/problems/single-number/
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4
思路:
因为题意是除了某个元素只出现一次以外,其余每个元素均出现两次,所以我们可以用栈来实现。当元素不在栈中时,入栈;当元素在栈中时,出栈。这样,我们可以保证栈中剩下的元素,就是只出现一次的元素。但是这种方法,时间复杂度和空间复杂度均不符合要求。
时间复杂度:O(n^2)
空间复杂度:O(n)
class Solution:
def singleNumber(self, nums: List[int]) -> int:
stack=[]
for num in nums:
if num not in stack:
stack.append(num)
else:
stack.remove(num)
return stack.pop()
思路:
用哈希直接记录每个元素出现的次数,最后遍历哈希表找到次数等于 1 的那个元素即可。但在这种思路依然不符合题意,因为我们用了线性的空间,同时我们还用了两次遍历,所以不是最优解。
时间复杂度:O(n)
空间复杂度:O(n)
class Solution:
def singleNumber(self, nums: List[int]) -> int:
hash={}
for num in nums:
if num not in hash:
hash[num]=1
else:
hash[num]+=1
for k,v in hash.items():
if v==1:
return k
思路:
既然以上的两种方法都不符合题意,那我们就要想想别的办法了。从题意可以知道,数组中只有一个元素出现一次,其余都出现两次。所以我们是不是可以用下数学的方法,比如异或操作。
异或运算有以下三个性质:
了解了以上三个性质,是不是就很简单了,遍历数组时不断的进行异或操作,因为异或操作满足交换律和结合律,所以相同的元素异或为 0 ,最后就剩下我们要找的只出现一次的元素了,同时空间复杂度也满足要求了。
时间复杂度:O(n)
空间复杂度:O(1)
class Solution:
def singleNumber(self, nums: List[int]) -> int:
res=0
for i in nums:
res^=i
return res
一行代码:
from functools import reduce # python2不需要引入
class Solution:
def singleNumber(self, nums: List[int]) -> int:
return reduce(lambda x,y:x^y,nums)
如果觉得文章不错,希望大家可以关注我噢,点赞、收藏、在看、分享就再好不过了。如果有任何建议和问题,可以在下方给我留言,我会不定期更新更多的文章,祝我们终将自由。