二进制数1
思路
题目非常直白:给一个非负整数,数一下它的二进制表示里有几个 1。
比如 3 的二进制是 11,有 2 个 1;65 的二进制是 1000001,也有 2 个 1。
怎么数?最经典的做法就是逐位检查——每次看最低位是不是 1,看完之后右移一位,直到整个数变成 0。具体来说:
- 用
n & 1取出最低位(如果是 1 就计数 +1) - 用
n >>= 1把 n 右移一位,相当于"扔掉"已经看过的最低位 - 重复上面两步,直到 n 变成 0
其实还有一个更巧妙的做法:n & (n - 1) 能把 n 最低位的 1 变成 0。每做一次就消灭一个 1,做几次就有几个 1。不过对于这道入门题,逐位检查就够了,简单明了。
代码
#include <iostream>
using namespace std;
int main() {
long long n;
cin >> n;
int cnt = 0;
while (n) {
cnt += n & 1;
n >>= 1;
}
cout << cnt << endl;
return 0;
}
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
long n = sc.nextLong();
int cnt = 0;
while (n > 0) {
cnt += (int)(n & 1);
n >>= 1;
}
System.out.println(cnt);
}
}
n = int(input())
print(bin(n).count('1'))
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
rl.on('line', (line) => {
let n = BigInt(line.trim());
let cnt = 0;
while (n > 0n) {
cnt += Number(n & 1n);
n >>= 1n;
}
console.log(cnt);
rl.close();
});
复杂度分析
- 时间复杂度:
,二进制位数就是
,每一位看一次。
- 空间复杂度:
,只用了一个计数器。
小结
这是一道位运算入门题。核心操作就两个:& 1 取最低位、>>= 1 右移。掌握了这两个操作,很多位运算的题目都能迎刃而解。如果想更高效地数 1 的个数,可以了解一下 n & (n-1) 这个技巧——它每次能精准消灭一个 1,循环次数等于 1 的个数而非总位数。



京公网安备 11010502036488号