下面为大家介绍三种解法,参照剑指offer官方题解,欢迎指正!!!!
1.右移解法
首先抛出来一个例子:

  • 假如我们有整数5,他的二进制表示为 0000 0101, 我们需要统计这个里面1的个数,首先初始化一个计数器 count = 0,不难想到的是我们可以使用 1 & 0000 0101 得到 1,则count += 1,在将5进行右移得到 0000 0010, 与 1 进行与运算,此时为0,计数器不加,继续将5右移一位得到 0000 0001, 1 & 0000 0001 得到1,count += 1,此时count = 2. 我们由此得到最终的结果.
    但我们考虑下如果是负数的情况,我们右移会使最右边的一位变成1而不是0,但是我们使用python进行负数补码的求解的时候,最终的结果是一个正整数,所以可以直接的使用右移的方法,但是其他语言我就不太清楚了,希望指正,代码如下:
    class Solution:
     def NumberOf1(self, n):
         # write code here
         count = 0
         if n < 0:
             n = n & 0xffffffff
         while n:
             if (n & 1):
                 count += 1
             n = n >> 1
         return count

2.左移解法

  • 同样上面的例子我们设置一个flag = 1, temp = 0, count = 1,下面我们分析过程:
    我们还是用 0000 0101 和 flag 进行与运算,但这次我们不必将负数进行补码的求解,开始 flag = 1, 与运算后 结果为1 ,则count += 1,temp += 1, 下面我们将flag进行左移,得到 10,再将其与0000 0101 进行与运算,得到 0, temp += 1,......继续一直这样运算下去,直到temp = 32(数字有32位),结束.代码如下:
    class Solution:
      def NumberOf1(self, n):
          # write code here
          temp = 0
          count = 0
          flag = 1
          while temp < 32:
              if flag & n:
                  count += 1
              flag = flag << 1
              temp += 1
          return count

3.更精简的运算

  • 还是先抛出一个例子:
    二进制数 1100,当我们将 1100 减去1 之后变成 1011, 将 1011 & 1100 得到1000, 可以发现一个正整数减去1,再和原整数做与运算后,会吧最右边的1变成0,那么一个整数的二进制表示中有多少个1就可以进行多少次这样的运算.但这个方法需要进行负数的补码转换,代码如下:
    class Solution:
    def NumberOf1(self, n):
        # write code here
        count = 0
        if n < 0:
            n = n & 0xffffffff
        while n:
            count += 1
            n = n & (n-1)
        return count