【剑指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 };