剑指Offer第十一题:二进制中1的个数
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
常规算法:获得这个数的二进制字符串,对字符串诸位计数
public int NumberOf1(int n) {
String s = Integer.toBinaryString(n);
int count = 0;
for(int i = 0; i<s.length(); i++){
if(s.charAt(i) == '1'){
count++;
}
}
return count;
}
按位与:
public int NumberOf1(int n) {
//按位与,对于一个数n和n-1,
//当n是正数时
//当n和n-1的二进制长度相同时(101,100),两个数只有一位是不相同的,且在最低位
//当n和n-1的二进制长度不相同时,(1000,111),n二进制中1的个数只有一个,两个数相与直接就是0
//当n是负数时
//-4 = 11111111111111111111111111111 100
//-5 = 11111111111111111111111111111 011
//对于n=-4 高位相同,低位只有一个1,一次按位与就可以
//-11 = 1111111111111111111111111111 0101
//-12 = 1111111111111111111111111111 0100
//对于n=-11 高位相同,只有最低位一位不相同
int count = 0;
while(n != 0){
count++;
n = (n&(n-1));
}
return count;
}
复习一个知识点:负数的二进制表示
负数的绝对值的二进制的反码+1,高位用1来填充,最高位的1为符号位
如-5:
绝对值:5,二进制101
101的反码:11111111111111111111111111111010
加1:11111111111111111111111111111011
所以-5的二进制表示就是:11111111111111111111111111111011
Integer.toBinaryString(int n) 可以直接获得n的二进制数组成的字符串