Leetcode191. 32位中二进制1的个数

89 阅读2分钟

191. 位1的个数 - 力扣(LeetCode)

暴力统计

就是自己要先把给的数字转为二进制,然后再去统计二进制中1的个数。 我刚开始以为这个二进制数给已经给好的,直接统计了,结果为0,其实是让自己转化的:

class Solution {
public:
    int hammingWeight(uint32_t n) {
           
          vector<int> v;
          
          //转二进制
          while(n)
          {
               v.push_back(n%2);
               n/=2;
          }
 
 
//统计1的个数
    int count=0;
    for(size_t i=0;i<v.size();i++)
    {
       if(v[i]==1)
       {
         count++;
       }
    }

return count;    
    }
};

时间复杂度应该是O(n),每个数都要遍历一遍,统计它的次数。但是二进制最多32位,o(1)吧?





Map


class Solution {
public:
    int hammingWeight(uint32_t n) {
      
          vector<int> v;
          //转二进制
          while(n)
          {
               v.push_back(n%2);
               n/=2;
          }

        unordered_map<int,int> OnceMap;
        
        //统计个数
        for(auto ch:v) OnceMap[ch]++;  

       //返回1的个数
       unordered_map <int,int>::iterator it=OnceMap.begin();
        int result=0;
       for( ;it!=OnceMap.end();it++)
       {
           if(it->first==1) 
           {
               result=it->second;
          
           } 
       }
          return result;
    }
};

这个代码的问题在于它没有正确地统计32位无符号整数n中1的个数,而是转换为二进制后再统计1的个数。在统计1的个数时,使用了一个unordered_map来存储每个数字出现的次数,然后再遍历map找到1出现的次数。这样做的效率比直接统计1的个数要低很多。

正确的做法是使用位运算来统计n中1的个数,可以使用一个循环,每次将n与1进行与运算,然后将n右移一位,直到n为0为止。在每次与运算的结果为1时,计数器加1。这样可以在O(1)的时间复杂度内完成统计。




位运算

1&1=1 0&1=0 判断是0是1

n>>1,遍历32位

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int count=0;
        int i=32;
        while(i--)
        {
            if(n&1)count++;
            n>>=1;
        }


        return count;
    }
};