题目链接
题目描述
给定一个非负整数 n
,请计算 0
到 n
之间的每个数字的二进制表示中 1
的个数,并输出一个数组。
示例 1:
输入: n = 2
输出: [0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10
示例 2:
输入: n = 5
输出: [0,1,1,2,1,2]
解释:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
说明 :
- 0 < = n < = 1 0 5 0 <= n <= 10^5 0<=n<=105
分析:
本题的关键在于 如何计算一个数的二进制中1的个数。
x& (x-1)
可以去除 x 最低位 的 1。
例如:
x = 10111(23)
x 10111
x-1 10110
x & (x - 1) = 10110,去除了最低的那位 1
x = 10110
x 10110
x-1 10101
x & (x - 1) = 10100,又去除了最低的一位1
…
一直重复这样的操作,直到x = 0。循环的次数就是 x 中 1 的个数
时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
C++代码:
class Solution {
public:
int fun(int x){
int cnt = 0;
while(x){
x &= (x - 1);
cnt++;
}
return cnt;
}
vector<int> countBits(int n) {
vector<int> res(n+1);
for(int i = 0;i <= n;i++){
res[i] = fun(i);
}
return res;
}
};
Java代码:
class Solution {
int fun (int x){
int cnt = 0;
while(x > 0){
cnt++;
x &= (x - 1);
}
return cnt;
}
public int[] countBits(int n) {
int[] res = new int[n+1];
for(int i = 0;i <= n;i++) res[i] = fun(i);
return res;
}
}