文章目录
- 一【题目类别】
- 二【题目难度】
- 三【题目编号】
- 四【题目描述】
- 五【题目示例】
- 六【解题思路】
- 七【题目提示】
- 八【题目进阶】
- 九【时间频度】
- 十【代码实现】
- 十一【提交结果】
一【题目类别】
- 动态规划
二【题目难度】
- 简单
三【题目编号】
- 338.比特位计数
四【题目描述】
- 给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
五【题目示例】
-
示例 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
六【解题思路】
- 利用动态规划的思想,通过观察示例可以发现:
- 当n是偶数时:此时数字对应二进制中1的个数和此数字除以2的数字对应二进制中1的个数相同,因为在二进制中乘除2相当于左移或右移,并不影响二进制数中1的个数
- 当n是奇数时:此时数字对应二进制中1的个数比此数字的前一个数字对应二进制中1的个数多一个,因为奇数比偶数不管在二进制还是十进制都多一个1
- 根据以上思路代码就很容易写出来了,思路转换为代码的详细内容可见代码
- 需要注意初始状态就是当前数字是0的时候,很明显此时0对应的二进制中1的个数为0个
- 最后返回结果即可
七【题目提示】
- 0 < = n < = 1 0 5 0 <= n <= 10^5 0<=n<=105
八【题目进阶】
- 很容易就能实现时间复杂度为 O ( n l o g n ) O(n log n) O(nlogn) 的解决方案,你可以在线性时间复杂度 O ( n ) O(n) O(n) 内用一趟扫描解决此问题吗?
- 你能不使用任何内置函数解决此问题吗?(如,C++ 中的 __builtin_popcount )
九【时间频度】
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n为传入的参数大小
- 空间复杂度: O ( n ) O(n) O(n),其中 n n n为传入的参数大小
十【代码实现】
- Java语言版
class Solution {
public int[] countBits(int n) {
int[] res = new int[n+1];
res[0] = 0;
for(int i = 0;i<=n;i++){
if(i % 2 == 0){
res[i] = res[i / 2];
}else{
res[i] = res[i / 2] + 1;
}
}
return res;
}
}
- C语言版
int* countBits(int n, int* returnSize)
{
int* res = (int*)malloc(sizeof(int) * (n + 1));
res[0] = 0;
for(int i = 1;i<=n;i++)
{
if(i % 2 == 0)
{
res[i] = res[i / 2];
}
else
{
res[i] = res[i / 2] + 1;
}
}
*returnSize = n + 1;
return res;
}
- Python版
class Solution:
def countBits(self, n: int) -> List[int]:
res = [0] * (n + 1)
res[0] = 0
for i in range(1,n + 1):
if i % 2 == 0:
res[i] = res[i // 2]
else:
res[i] = res[i // 2] + 1
return res
十一【提交结果】
-
Java语言版
-
C语言版
-
Python语言版