面试题 10:二进制中1的个数
标签 :剑指Offer
问题描述:
统计一个整数n的二进制表示中1出现的次数。
考虑:
该整数为0的情况;
该整数为负数的情况;
思路:
- 右移法
将该整数n和1做与操作,如果结果为1,说明最低位是1,如果结果为0,说明最低位为0。循环使整数n右移一位,统计1出现的次数,直到n为0,循环结束。32位整数要循环32次。
public int NumberOf1(int n){
int count = 0;
while(n != 0){
if(n & 1 == 1) count++;
n = n >> 1;
}
return count;
}
因为负数右移时,最高位一直产生1,该解法遇到负数时会死循环。
- 左移法
左移法能解决负数问题。思路是使用一个临时变量,从1开始,一直左移,并和n做与操作。如果结果不为0,说明当前位是1,如果结果为0,说明当前位是0。直到临时变量为0,循环结束。32位整数要循环32次。
public int NumberOf1(int n){
int count = 0;
int flag = 1;
while(flag != 0){
if(n & flag != 0) count++;
flag = flag << 1;
}
return count;
}
- 特殊法
一个整数与自身减1做与操作,能消去该整数的最右边的一个1。这条规则对于所有整数都适用。整数有几个1,循环就执行几次。
public int NumberOf1(int n){
int count = 0;
while(n != 0){
count++;
n = n & (n - 1);
}
return count;
}
题目变形:二进制中0的个数
- 用32减去1的个数。
- 一个整数和自身加1做或操作,能把最右边的0变成1。一直循环判断,直到n+1为0,循环结束。