只出现x次的数字–巧用异或
入门级:只出现一次,其余数字出现了偶数次
很简单了,直接利用异或的性质,每次将数组所有数字的异或在一起,因为其他数字都出现了偶数次,所以异或结果就是唯一的奇数次的。
class Solution:
def singleNumber(self, nums: List[int]) -> int:
ans = 0
for i in nums:
ans ^= i
return ans
升级版:两个元素出现1次,其余出现两次
如果数组中有两个数字,问题就变的复杂了起来。因为难以区分两个数字。但是如果我们还是利用异或的性质的话还是可以发现一些端倪的。我们将整个数组异或起来,最后的结果肯定是两个数单独数字的异或和。因此我们可以分析这个二进制的数字,如果某一位是1说明两个数字在该位分别是0和1。因此我们可以利用这个特点对两个数字进行区分。
class Solution:
def singleNumber(self, nums: List[int]) -> List[int]:
cur = 0
for i in nums:
cur ^= i
h = cur&(-cur) # 找出cur的最后一个1, h=00000010000
a = 0
b = 0
for i in nums:
if h&i == 0:
a ^= i
else:
b ^= i
return [a, b]
最终版:其余元素出现了三次
这个就比较麻烦了,需要借助状态转移的方法,因为我们要转换为3进制。保证每次计数时候,从00-->01-->10-->00
因此我们借助one和two两个。进行考虑。
参考题解
class Solution:
def singleNumber(self, nums: List[int]) -> int:
one = 0
two = 0
for i in nums:
one,two = (one^i)&(~two), ((~one)&(two&~i))|(one&i)
return one