剑指 11 二进制数中1的个数
一、题目概述
输入一个整数,输出该数32位进二进制表示中1的个数。其中负数用补码表示
这是一个要利用到进制移位的问题
以前做进制的题目的时候总有点混,所以现在来补充一下进制上的知识
考虑几个补码中的基础知识:
- 正数右移:保持为正数,相当于/2。
- 负数右移:保持为负数,移位前是负数,移位后保持是负数,因此移位后最高位设为1。如果一直右移,最终会变成-1,即(-1)>>1是-1。
- 正数左移:不保持为正数,相当于*2。(注意:1左移31时为负数最大值)
- 负数左移:不保持为负数,在左移的过程中会有正有负的情况。所以切记负数左移不会特殊处理符号位。如果一直左移,最终会变成0。
考虑操作逐位数统计
对于1,每一次 < < 1 << 1 <<1即左移1位,然后与 n n n进行 & \& &操作,能够统计每一个位上是否为1,当最终移位使得flag为0时,即移位结束(32位)
考虑操作 n & ( n − 1 ) n \& (n-1) n&(n−1)
在二进制中
n
n
n与
n
−
1
n-1
n−1的二进制表示,为
n
n
n从个位开始到出现的第一个1与
n
−
1
n-1
n−1相反,其它位均相同。
因此
n
&
(
n
−
1
)
n\&(n-1)
n&(n−1)得到的结果是消除了从个位开始第一个
1
1
1的
n
n
n的二进制表示。
当最终变为0时结束。
二、代码
# -*- coding:utf-8 -*-
class Solution:
def NumberOf1(self, n):
count =0
while(n & 0xffffffff != 0):
n = n & (n-1)
count+=1
return count