题目描述
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
样例描述
示例 1:
输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10
思路
**暴力位运算 / 奇偶分类找规律 + 动态规划 / 动态规划 + 位运算 **
- 每次将数与1做&运算看是否等于1,是1的话就累计,然后让该数右移一位。 逐次右移比较,直到为0。
方法二:
列举几个例子可以发现,奇数中1的个数比 比它下小的最大的数 多1,多的1就是二进制末尾的1,某偶数x中1的个数与x / 2的1的个数相等
方法三:动态规划 + 位运算
可以根据二进制求找一个递推式,第i位1的个数等于右移1加上末位1是否为1
代码
class Solution {
public int[] countBits(int n) {
int ans[] = new int[n + 1], idx = 0;
for (int num = 0; num <= n; num ++ ) {
int res = 0;
int t = num;
while (t != 0) {
res += (t & 1);
t >>= 1;
}
ans[idx ++] = res;
}
return ans;
}
}
方法二:
class Solution {
public int[] countBits(int n) {
int res[] = new 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 - 1] + 1;
}
}
return res;
}
}
方法三:
class Solution {
public int[] countBits(int n) {
int f[] = new int[n + 1];
f[0] = 0;
for (int i = 1; i <= n; i ++ ) {
f[i] = f[i >> 1] + (i & 1);
}
return f;
}
}