问题1: 一个数组中,除了其中一个元素只出现一次之外,其它元素都出现了两次,怎么快速找到只出现一次的元素?

问题2: 一个数组中,除了其中一个元素只出现一次之外,其它元素都出现了三次,怎么快速找到只出现一次的元素?

对于问题1比较容易解决,将所有的元素异或:ans^=x得到的就是只出现一次的元素。这是因为,相同元素异或(^)为0,出现偶数次的元素异或之后为0,0与只出现一次的元素异或就是该元素本身,这个很好理解。

对于问题2,虽然不能直接用异或,但是同样需要从位操作的角度来考虑。我的思路是: 1.将数据的元素表示为二进制的形式,并将对应的位相加; 2.如果对应的位之和能被3整除,说明只出现一次的元素对应的二进制位为0,否则为1;

但是有个问题是这个方法是不是最后的实现比采用排序和hashmap两种方法复杂度更高?

其实不然,可以采用一个中间变量来保存相加过程中的进位。先看代码:

def special(lst):
    ones = 0
    twos = 0
    for x in lst:
        twos |= ones & x
        ones ^= x
        not_threes = ~( ones & twos )
        ones &= not_threes
        twos &= not_threes
    return ones

可以把变量ones看成是数组中元素二进制表示之后相加之和(进位保存在twos中),twos看成是进位,twos |= ones & x就是将进位保存在twos中,ones ^= x就是元素相加,如果ones对应位为1,twos对应也为1,那 么说明对应位之和就为3了,那么就要消除掉。如果题目改为只有一个元素出现两次,那么返回就是twos了。