【剑指Offer】面试题10:二进制中1的个数

来源:互联网 发布:守望先锋性能数据 ping 编辑:程序博客网 时间:2024/06/06 12:48

一:题目描述

输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

二:解体分析

负数的补码=原码取反(符号位不取反)+1  //第一位为符号位 1负数  0正数
有考虑负数,有考虑补码,思路混乱了
以为需要把整数转化为二进制,其实不用,因为用整数直接与1或0进行位运算就可以

po一下剑指Offer的解题思路

第一种:可能会引起死循环的解法(这里就不介绍了)

第二种:

首先把n与1做与运算,判断n的最低位是不是1,

接着把1左移一位得到2,再和n做与运算,就能判断n的次低位是不是1

....

这样反复左移,每次都能判断n的其中一位是不是1

class Solution {public:     int  NumberOf1(int n) {         int count=0;         unsigned int flag=1;         while(flag){             if(n & flag)                 count++;             flag=flag<<1;//左移一位相当于乘以2,         }//直到flag的二进制表示均为0结束                  return count;     }};
循环的次数等于整数二进制的位数,int占4个字节,每个字节占8位,所以32位的整数需要循环32次

第三种:

下面介绍的的方法,整数中有几个1就只需要循环几次

一个数减去1,如果这个数不等于0,那么该数的二进制表示至少有一位1

假设这个数最右边一位是1,那么减去1后,最后一位变成0,而其他所有位保持不变

假设整数的二进制表示中最右边1位于第m位,那么减去1后,第m位由1变成0,第m位后面的所有0都变成1,第m位前的所有位保持不变

前面的两种情况,我们发现把一个整数减去1后,都是把最右边的1变成0,如果它的右边还有0的话,所有的0都变成1,而它左边的所有位保持不变

接下来我们把一个整数减去1与该整数做与运算

如1100

减去1后的结果 1011

与运算的结果1000

class Solution {public:              int count=0;         while(n){             count++;             n=(n-1) & n;         }         return count;     }};

相当于一次该运算消去整数二进制表示中的一个1

那么整数二进制表示中有多少个1,就进行多少次这样的运算


原创粉丝点击