Given an array of integers, every element appears three times except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
题解1:
线性,但是使用额外空间的办法。
python 开一个dict记录每个数字出现的次数,然后扫一遍dict,找到次数为1的并return
Code1:
class Solution:
# @param A, a list of integer
# @return an integer
def singleNumber(self, A):
d = {'0' : 0}
for i in A:
s = str(i)
if s in d :
d[s] += 1
else :
d[s] = 1
for s in d:
if d[s] == 1:
return int(s)
return 0
题解2:
位运算,可以达到线性,并且不使用额外空间(一个用来“遍历‘的变量还是要的...)
思想是,一个数字出现三次,那么按位相加的话,每个位上应该是3。
那么,把所以数字加起来,每个位上mod 3 之后,余1的位,就是只出现1次的那个数字的。
普遍办法是,开一个list,记录每个位的和。但是那样就有额外空间了。
极限办法是,用3个变量,每个变量的每个位分别代表”这个位出现了1次\2次\0次 (mod 3之后)
为了不多用空间,我的代码中:
A[1]的每个位上代表“这个位出现了1次
A[2]的每个位上代表“这个位出现了2次
Code2:
class Solution:
# @param A, a list of integer
# @return an integer
def singleNumber(self, A):
if len(A) == 1:
return A[0]
#Every bit in A[1] means this bit occurs 1 time
#Every bit in A[2] means this bit occurs 2 times
#Every bit in A[0] means this bit occurs 3 times(mod 3 == 0)
i = A[2]
A[2] = A[1] & i
A[1] ^= i
A[2] |= A[1] & A[0]
A[1] ^= A[0]
A[0] = A[1] & A[2]
A[1] &= ~A[0]
A[2] &= ~A[0]
for i in A[3:]:
A[2] |= A[1] & i #if the bit occurs both in A[1] and the new number, then it occurs 2 times
A[1] ^= i
A[0] = A[1] & A[2] #if it occurred 1 time & 2times, then it occurred 3 times(mod 3 == 0)
A[1] &= ~A[0] #if the bit occurred 3 times, then it doesn't belong to A[1],A[2]
A[2] &= ~A[0] #which means the bit occurred 1 time and 2 times
return A[1]
Ps:
因为我借用了list里的A[0] A[1] A[2] , 所以要考虑给的list里只有1个元素的特殊情况
参考:
http://www.acmerblog.com/leetcode-single-number-ii-5394.html
其他类似题目:
1. 每个数字出现两次,只有一个数字出现一次(直接将所有数字进行异或即可,因为相同数字异或得0)