【剑指offer】57.二进制中1的个数

总目录:

算法之旅导航目录

 

1.问题描述

输入一个整数 n ,输出该数32位二进制表示中1的个数。其中负数用补码表示。
数据范围:- 2^{31} <= n <= 2^{31}
即范围为:-2147483648<= n <= 2147483647

 

2.问题分析

 题中主要信息:

(1)统计32位整型有符号数二进制中1的个数

(2)因负数用补码表示,故不能用连除法,因为向右移位会补1

解决办法:

1循环按位比较法

不要动原数值,而是将1向左移位(右侧自动补0)与输入值作与运算看是否为0

2利用n&(n-1)

 如果一个整数不为0,那么这个整数至少有一位是1。如果我们把这个整数减1,那么原来处在二进制中最右边的1就会变为0,这个1后面的所有的0都会变成1(如果最右边的1后面还有0的话),且这个1前面的所有位将不会受到影响。

由此n&(n-1)如果不为0,则说明高位还有1,则继续作上述运算。


3.代码实例

循环按位比较法

 1 class Solution {
 2 public:
 3     int NumberOf1(int n) {
 4         int res = 0;
 5         //遍历32位
 6         for(int i = 0; i < 32; i++){
 7             //按位比较
 8             if((n & (1 << i)) != 0)   
 9                 res++;
10         }
11         return res;
12      }
13 };

利用n&(n-1)

 1 class Solution {
 2   public:
 3     int NumberOf1(int n) {
 4         int res = 0;
 5         //遍历32位
 6         while (n != 0) {
 7             n &= n - 1;
 8             res++;
 9         }
10         return res;
11     }
12 };

 

posted @ 2022-12-02 16:59  啊原来是这样呀  阅读(34)  评论(0编辑  收藏  举报