c++
首先将10进制转换为2进制,然后统计其中1的个数。
这里需要注意一些特殊形式的数,因此考查了进制转换、以及正负数二进制存储的一些标准。
因此最直接思路如下:
class Solution { public: int NumberOf1(int n) { int ans=0; while ( n!=0){ int tmp = n%2; if(tmp ==1)ans++; n=n/2; } return ans; } };
但是针对有一些特殊情况无法判断:
32位二进制 能够表示
源码:
补码:
按照这个计算思路:
class Solution { public: int NumberOf1(int n) { vector<int> bin(32,0); if (n<0) bin[31]=1; int index=0; while(n != 0){ if (n%2) bin[index]=1; index++; n = n/2; } if (bin[31]==1){ for(int i=0; i<31; i++){ bin[i]=!bin[i]; } index =0; bin[index]++; while(bin[index] == 2){ bin[index]=0; index++; bin[index]++; } bin[31]=1; } int ans=0; for(int i=0; i<=31; i++){ if(bin[i] == 1) ans++; } if (bin[31]==1 && ans==1){ return 1; }else{ return ans; } } };
PS: 其中正数区域可以计算,负数求余需要+1, 最小的数求余要+1
二进制存储: 反码的补码。
先计算源码-----取反-------+1
利用移位直接操作:
class Solution { public: int NumberOf1(int n) { int mask =0x01; int ans=0; while(mask !=0){ if(mask & n) ++ans; mask<<=1; } return ans; } };
另外一种思路,利用二进制一个特性:如1100&1011=1000.也就是说,把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0.那么一个整数的二进制有多少个1,就可以进行多少次这样的操作,计算个数,但是效率比较低。
class Solution { public: int NumberOf1(int n) { int ans=0; while(n!=0){ ans++; n=n&(n-1); } return ans; } };