原题地址:http://oj.leetcode.com/problems/single-number-ii/
题意:Given an array of integers, every element appears three times except for one. Find that single one.
要求:和single number一样,线性时间复杂度,不能使用额外空间。
解题思路:这道题就比较难了。也是考察位操作。网上的位操作解法看了好半天也没有得其精髓。由于序列中除了那唯一的一个数之外所有的数都是三个三个出现的。如果把这些数都转换成二进制,那么二进制数中1的那些位会连续出现三次,我们可以利用这个思路来解题。比如:3331222转换成二进制为:11 11 11 01 10 10 10。在第1位上,1出现了4次。第2位上,1出现了6次。那么我们把每一位上为1的个数mod 3剩下的1就是我们所求的数,比如这个例子:4 mod 3 = 1; 6 mod 3 = 0。这样剩下的二进制位为:01。那最后所求的数就是1了。
那怎么实现这个想法呢?使用二进制模拟三进制。在连续来3个1后清0。使用两个bit位,bit1和bit2。初始状态bit1和bit2都是0,即00,在来了第一个1后,变成了01,来了第二个1后变成了10,来了第三个1后,变成了11,然后清0为00,即:00->01->10->11,然后将11清为00,这个过程就是我们编程的思路。比如如果输入序列为:1 1 1 1 1 1 1,则变化过程为:00->01->10->11->00->01->10->11->00->01,最后剩下的是1,也就得到了结果。如果位数多那么以此类推,比如序列为:3 3 3 2 2 2 1。则二进制为:11 11 11 10 10 10 01。则低位为1 1 1 0 0 0 1,变化过程为:00->01->10->11->00->00->00->00->01,所以低位剩下1。高位为:1 1 1 1 1 1 0,变化过程为:00->01->10->11->00->01->10->11->00->00,所以高位剩下0。那么最后剩下的是01,也就是1。如果位数更多,可以以此类推。程序中的one相当于bit1,two相当于bit2。
代码:
class Solution: # @param A, a list of integer # @return an integer def singleNumber(self, A): one = 0; two = 0; three = 0 for i in range(len(A)): two |= A[i] & one #two为1时,不管A[i]为什么,two都为1 one = A[i] ^ one #异或操作,都是1就进位 three = ~(one & two) #以下三步的意思是:如果one和two都为1时,就清0,反之则保持原来状态。 one &= three two &= three return one
以上是网上的精髓解法,我自己还有个弱智的解法,供参考:
def singleNumber(self, A): dict = {} for i in range(len(A)): if A[i] not in dict: dict[A[i]] = 1 else: dict[A[i]] += 1 for word in dict: if dict[word] == 1: return word