解题思路
计算一个整数的二进制表示中1的个数有几种常用方法:
-
位运算法:
- 使用
判断最低位是否为1
- 右移运算
检查下一位
- 循环直到
变为0
- 使用
-
Brian Kernighan算法:
- 利用
可以消除最右边的1
- 每次操作都会消除一个1,直到
变为0
- 操作次数即为1的个数
- 利用
代码
#include <iostream>
using namespace std;
int countOnes(int n) {
int count = 0;
while (n) {
n = n & (n - 1); // 消除最右边的1
count++;
}
return count;
}
int main() {
int n;
while (cin >> n) {
cout << countOnes(n) << endl;
}
return 0;
}
import java.util.Scanner;
public class Main {
public static int countOnes(int n) {
int count = 0;
while (n != 0) {
n &= (n - 1); // 消除最右边的1
count++;
}
return count;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
System.out.println(countOnes(n));
}
}
}
def countOnes(n):
count = 0
while n:
n &= (n - 1) # 消除最右边的1
count += 1
return count
while True:
try:
n = int(input())
print(countOnes(n))
except:
break
算法及复杂度
- 算法:Brian Kernighan算法
- 时间复杂度:
,其中k是二进制中1的个数
- 空间复杂度:
这个解法使用了Brian Kernighan算法,比普通的位运算方法更高效,因为它只需要循环1的个数次,而不是整数的位数次。对于输入数据范围 ,这个方法都能高效处理。