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;
}
};
京公网安备 11010502036488号