136
给定一个整数数组,除了某个元素外其余元素均出现两次。请找出这个只出现一次的元素。
备注:
你的算法应该是一个线性时间复杂度。 你可以不用额外空间来实现它吗?
解析:不能用额外空间,所以哈希表也就是字典是不能用了,那就只能位操作了,用异或运算,a^a=0,所以出现两次的数都就消除了,最后剩下那个只出现一次的数
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
rst = nums[0]
for i in range(1,len(nums)):
rst = rst ^ nums[i]
return rst
137
给定一个整型数组,除了一个元素只出现一次外,其余每个元素都出现了三次。求出那个只出现一次的数。
注意:
你的算法应该具有线性的时间复杂度。你能否不使用额外的内存来实现?
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
ones, twos = 0, 0
for i in range(len(nums)):
ones = (ones ^ nums[i]) & (~twos)
twos = (twos ^ nums[i]) & (~ones)
return ones
260
给定一个整数数组 nums,其中恰好有两个元素只出现一次,其他所有元素均出现两次。 找出只出现一次的那两个元素。
示例:
给定 nums = [1, 2, 1, 3, 2, 5], 返回 [3, 5].
注意:
结果的顺序并不重要,对于上面的例子 [5, 3] 也是正确答案。
你的算法应该具有线性复杂度,你能否仅使用恒定的空间复杂度来实现它?
解析:这里需要解释下异或运算的含义,异或就是找两个数不相同的位,我们很容易通过一次循环找到两个数的异或结果c,有了c怎么找到这两个数呢,首先找到他们第一个不相同的位,即通过firstBit = rst_xor & ~(rst_xor - 1)找到最低的不相同位,然后让所有在这一位上取值为1的数异或,那么就获得其中一个数a,有了a和c,那么b就很容易获得了
c = a^b
a = c^b
b = c^a
class Solution(object):
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
rst_xor = nums[0]
rst = [0,0]
for i in range(1,len(nums)):
rst_xor = rst_xor ^ nums[i]
firstBit = rst_xor & ~(rst_xor - 1)
for i in range(len(nums)):
if(nums[i] & firstBit):
rst[0] = rst[0] ^ nums[i];
rst[1] = rst_xor ^ rst[0]
return rst
增加题目
一个整型数组里除了三个数字之外,其他的数字都出现了两次。请找出这三个只出现一次的数字?
解析:假设这三个数是a b c,那么通过异或运算可以得到三个数的异或值,即d=a^b^c,所以题目等价于:假设一个数组中有3个不同的数字 a、b 和 c,已知 aXORbXORc = a ^ b ^ c ,求 a、b 和 c 。
根据异或特性可以得知:
(aXORbXORc ^ a) ^ (aXORbXORc ^ b) ^ (aXORbXORc ^ c) = 0
若令X=aXORbXORc ^ a Y=aXORbXORc ^ b Z=aXORbXORc ^ c,
X^Y^Z=0,那么X Y Z 三个数中找到低位中第一个不为0的位置,在这个位置上X Y Z有三种可能:111、010、101(000不用考虑,因为找的就是不为0的位置),而X^Y^Z=0,所以只可能是101,也就是两个相同一个不同,那么可以通过异或获得那个不同的数,也就是如果我们获取到这三个数的低位第一个为1的位置后,进行异或,并令低位第一位为1的位置为firstBit ,就可以找到三个中不同的那个,即遍历这三个数X Y Z,如果发现某个数异或 aXORbXORc 等于 firstBit ,这个数就是不为0的最低位不同的那个数,令这个数为a,找到它之后b^c=aXORbXORc ^ a,再根据上一题的方法就能找到b c
class Solution(object):
def getFirstBit(self,num):
return num & ~(num-1)
def singleThreeNumber(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
abc = nums[0]
bc = 0
rst = [0,0,0]
firstBit = 0
for i in range(1,len(nums)):
abc = abc ^ nums[i]
for i in range(len(nums)):
firstBit = firstBit ^ Solution().getFirstBit(abc ^ nums[i])
firstBit = Solution().getFirstBit(firstBit)
for i in range(len(nums)):
if(Solution().getFirstBit(abc ^ nums[i]) == firstBit):
rst[0] = rst[0] ^ nums[i]
bc = abc ^ rst[0]
secondBit = bc & ~(bc - 1)
for i in range(len(nums)):
if(nums[i] & secondBit):
rst[1] = rst[1] ^ nums[i];
rst[2] = bc ^ rst[1]
return rst
参考:
https://blog.csdn.net/su20145104009/article/details/51295067