题目
输入一个32位整数,输出该数二进制表示中1的个数。
注意:
负数在计算机中用其绝对值的补码来表示。
样例1
输入:9
输出:2
解释:9的二进制表示是1001,一共有2个1。
样例2
输入:-2
输出:31
解释:-2在计算机里会被表示成11111111111111111111111111111110,一共有31个1。

解法1:位运算循环

难点在于如何处理负数
C++中右移一个负数,会在最高位补上符号位,这样负数就会不停补上1,因此我们可以先将其转换成无符号整数,这样右移最高位补0
时间复杂度O(logn),空间复杂度O(1)

  1. class Solution {
  2. public:
  3. int NumberOf1(int n) {
  4. int ans = 0;
  5. unsigned int a = n;
  6. while (a) {
  7. ans += a & 1;
  8. a >>= 1;
  9. }
  10. return ans;
  11. }
  12. };

解法二:位运算特殊操作

n & (n - 1)可以把n中最右边的1变成0,其余位保持不变
这样时间复杂度就降至O(k),k是n中1的个数,空间复杂度O(1)

  1. class Solution {
  2. public:
  3. int NumberOf1(int n) {
  4. int ans = 0;
  5. while (n) {
  6. ans++;
  7. n = n & (n - 1);
  8. }
  9. return ans;
  10. }
  11. };