题目来源:https://leetcode-cn.com/problems/counting-bits
题目描述
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
示例一
输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10
示例二
输入:n = 5
输出:[0,1,1,2,1,2]
解释:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
解法一
常规思路,分别计算每个数字所对应的二进制数字中含有1的个数。
对于二进制中1的个数的求解,详细见:https://blog.csdn.net/weixin_45865773/article/details/123584905
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> ret;
for(int i=0; i<=n; i++){
int temp = i;
int sum = 0;
while(temp > 0){
if(temp%2 == 1){
sum++;
}
temp >>= 1;
}
ret.push_back(sum);
}
for(int i=0; i<=n; i++)
cout << ret[i] << ' ';
return 0;
}
//Input 5
//Output 0 1 1 2 1 2
时间复杂度为:nlogn
解法二(DP)
- 对于奇数,该数中1的个数一定比前一个偶数中1的个数多一个;
- 对于偶数,该数中1的个数和 该数/2 中1的个数一样(例如,对于2(二进制10),该数字除以2,就是该数字右移一位,将二进制的最后一个0移去,对1的个数没有影响。)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<int> ret(n+1);
ret[0] = 0;
for(int i=1; i<=n; i++){
if(i % 2 == 1){
ret[i] = ret[i-1] + 1;
}else{
ret[i] = ret[i/2];
}
}
for(int i=0; i<=n; i++)
cout << ret[i] << ' ';
return 0;
}
//Input 5
//Output 0 1 1 2 1 2
时间复杂度为: n