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?
Single number 的扩展题~除了一个元素,其他元素都出现了3次,找到那个元素~ 如果每个元素都出现了3次,那么每一个bit上出现1的次数也就是3的倍数,可以把数组的数都按位相加,然后对每一位都取余3,那么结果就是那个要找的数~值得注意的是,用python写的话要注意处理负数的情况(用c++或java写的话不用处理,直接返回就行)~刚开始不明白为什么用python写还要处理负数的情况,后来问了某人,貌似是因为python中没有数值溢出的概念,如果超出int的范围会自动扩充到long, 还不是很确定,以后弄清楚了再补充吧~
class Solution:
# @param A, a list of integer
# @return an integer
def singleNumber(self, A):
if A is None: return None
count = [0] * 32
for i in xrange(32):
for num in A:
count[i] += (num >> i) & 1
res = 0
for i in xrange(32):
res += (count[i] % 3) << i
if count[-1] % 3 == 1:
# manually revert the thing: -i = (~i) + 1 or ~(i - 1)
res = -(res - 1 ^ (1 << 32) - 1)
return res
写这题之前对二进制的补码概念一直还比较模糊,所以加一点概念知识在这里~
原码表示法规定:用符号位和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。
反码表示法规定:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。
补码表示法规定:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1.
正零和负零的补码相同,[+0]补=[-0]补=0000 0000B
从补码求原码的方法跟原码求补码是一样的 ,也可以通过完全逆运算来做,先减一,再取反
ps: python中运算符优先级:从最低的优先级到最高的优先级~(二进制运算优先级:取反运算符 > 左移运算符 > 右移运算符 > 按位与运算符 > 按位异或运算符 > 按位或运算符)
运算符 | 描述 |
---|---|
lambda | Lambda表达式 |
or | 布尔“或” |
and | 布尔“与” |
not x | 布尔“非” |
in,not in | 成员测试 |
is,is not | 同一性测试 |
<,<=,>,>=,!=,== | 比较 |
| | 按位或 |
^ | 按位异或 |
& | 按位与 |
<<,>> | 移位 |
+,- | 加法与减法 |
*,/,% | 乘法、除法与取余 |
+x,-x | 正负号 |
~x | 按位翻转 |
** | 指数 |
x.attribute | 属性参考 |
x[index] | 下标 |
x[index:index] | 寻址段 |
f(arguments...) | 函数调用 |
(experession,...) | 绑定或元组显示 |
[expression,...] | 列表显示 |
{key:datum,...} | 字典显示 |
'expression,...' | 字符串转换 |