剑指offer.11.二进制中1的个数
题目描述
输入一个整数,输出该数32位二进制表示中1的个数。其中负数用补码表示。
代码实现
import java.util.ArrayList;
public class Solution {
public int NumberOf1(int n) {
// 法1
int cnt = 0;
int mark = 1;
while (mark != 0) {
cnt += (n & mark) == 0 ? 0 : 1;
mark <<= 1;
}
return cnt;
// 法2
int cnt = 0;
while (n != 0) {
cnt++;
n = n & (n - 1);
}
return cnt;
}
}
分析
法一:按位与。从左往右按位与运算,计数即可。注意调整的为mark而非n,因为若n为负数,则向右移位操作时会补1,不会出现0的终止标志
时间复杂度:O(32)
空间复杂度:O(1)
法二:运算技巧。对于n=0x01010110,n-1=0x01010101,n&(n-1)=0x01010100,即每进行这样一次操作,就可去掉n最右边的一个1
时间复杂度:O(n),n为二进制中1的个数
空间复杂度:O(1)