剑指Offer--二进制中1的个数(Python)
牛客网链接
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
解法1(不考虑负数的情况)
每次检查n的最低位是否为1,进而更新1的个数,之后将n右移。但是对于负数,在右移的过程中将会在最左端补符号位1(正数补零),将造成死循环,因此该算法不可行(Python中对bin(-1)得到的不是-1的补码,而是-0b1(即在1的原码之前加负号,便于阅读...后面会进行详细的解释))
class Solution: def NumberOf1(self, n): count = 0 while n : if n & 1: count+=1 n >>= 1 return count
解法2
flag置为1,每次左移flag,来判断相应位是否为1
(因为python会在int过大时自动将int转为long,因为我们需要使用python中的c语言类型)
class Solution: def NumberOf1(self, n): flag = 1 count = 0 # 将flag转为c语言中的int类型(flag经过移位之后将超过C语言中最大整数将会得到0,退出循环) while c_int(flag) : if n & flag: count+=1 flag <<= 1 return count
解法3
如果数字不为0,说明存在为1的值,进行n&(n-1)运算,将会得到去掉最低位1之后的结果
例如n = 01100,则n-1=01011,两者按位与n&(n-1)=01000,即为n去掉最后一个1之后的结果
因为bin(-1)将得到-0b1,我们这里期望得到-1的补码
因此需要先将n&0xffffffff得到数字对应的补码(在Python中,负数和0xffffffff按位与之后变成一个无符号数,二进制表示为编码形式)
class Solution: def NumberOf1(self, n): print(bin(n)) # write code here count = 0 n &= 0xffffffff while n: n = n&(n-1) count+=1 return count