给定整数数组,每个元素出现三次,除了一个出现恰好一次。找到那个单一的。

这道题如果换成“给定整数数组,每个元素出现两次,除了一个出现恰好一次。找到那个单一的。”会简单很多,因为利用异或操作符,可以把两个相同的元素消掉。比如:a^a=0。

但是现在问题是出现了三次,先放上代码:

1
2
3
4
5
6
7
def singleNumber(A):
ones = 0
twos = 0
for i in A:
ones = (ones ^ i) & ~twos
twos = (twos ^ i) & ~ones
return ones

这代码一看就懵逼。而且对于不熟悉位操作的人,简直就是痛苦。WTF?
这段代码看上去很诡异,但其实它是有来头的。

就像异或操作那样,我们把两个相同的元素消掉为0,那为何不想想如何把3个给消掉呢?很遗憾,计算机没有提供这样的操作符。但是你可以自定义。

如何做呢?我们需要一个像计数器一样的东西,这个东西能记住每一位上1所出现的次数。例如本道题,可以认为出现3次就归零。这个计数器也用位来表示,那么它的状态变化就是00->01->10->00。

比如一个数组[3,3,3,1],不用想,它的结果为1。在这里我描述一下过程。

首先来了个3,计数器,一开始肯定是00,3用二进制表示就是11,那么它