二进制中1的个数
二进制中1的个数
- 参与人数:3525时间限制:1秒空间限制:32768K
- 通过比例:32.44%
- 最佳记录:0 ms|0K(来自 牛客767990号)
题目描述
输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
1 解法1: 2 /* 3 这样,当n为负数的时候(eg: n = 0x80000000),会导致死循环。 4 因为在右移时,如果数字是一个无符号数值,则用0填补最左边的n位, 5 如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。 6 即,如果数字原先是一个正数,则右移之后在最左边补n个0; 7 如果数字原先是一个负数,则右移之后在最左边补n个1。 8 eg: 负数0x80000000右移一位后变为0xC0000000,如果一直做右移运算, 9 最终该数字会变成0xFFFFFFFF而陷入死循环。 10 */ 11 int NumberOf1(int n) { 12 int cnt = 0; 13 while (n){ 14 if (n & 1) 15 cnt++; 16 n = n >> 1; 17 } 18 return cnt; 19 }
1 解法2: 2 /* 3 不用右移输入的数字n,而是将unsigned int类型的1进行左移运算, 4 然后将n和1做与运算,从右向左依次判断n的第i位是否为1。 5 但是该解法中,循环的次数等于整数二进制的位数,32位整数需要循环32次。 6 */ 7 class Solution { 8 public: 9 int NumberOf1(int n) { 10 int cnt = 0; 11 unsigned int tmp = 1; 12 while (tmp){ 13 if (n & tmp) 14 cnt++; 15 tmp = tmp << 1; 16 } 17 return cnt; 18 } 19 };
1 解法3: 2 /* 3 把一个整数n减1,然后再与原整数n做与运算,可以将该整数最右边的1变为0。 4 即 (n-1) & n 将n的最右边的1变为0。 5 eg: n = 1100, 则n-1 = 1011, (n-1)&n = 1000. 6 因此,该解法,数字n中有多少个1,就循环多少次。 7 */ 8 class Solution { 9 public: 10 int NumberOf1(int n) { 11 int cnt = 0; 12 while(n){ 13 cnt++; 14 n = (n-1) & n; 15 } 16 return cnt; 17 } 18 };