比特位计数
常青
1 个月前
1 个月前
题目
给定一个非负整数 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
解题思路
针对这个题目,我们有两种方法可以解决,可以使用 奇偶数的二进制特性
或者通过 x = x & (x-1)
来消 去最小位的 1 去求解。
奇偶数的二进制特性
对于偶数: 1的个数等于减半的数的1的个数。
对于奇数: 就是减一的那个偶数的1的个数再加上1。
所以我们可以从 1 开始到 n 进行遍历,将结果存储在 result
变量中,如果 i 为偶数,则直接使用减半的数的 1 的个数即可,如果为奇数,则使用减一的那个偶数的1的个数再加上1。
- 判断奇偶可以使用与 1 进行与运算的方式来判断。
- 减半,即除以 2 可以使用 >> 右移的位运算来实现
class Solution {
public int[] countBits(int n) {
int[] result = new int[n+1];
result[0] = 0;
for(int i = 1; i<=n; ++i){
result[i] = (i&1) == 1 ? result[i-1]+1 : result[i >> 1];
}
return result;
}
}
消 1 法
通过 x = x & (x-1)
消去最小位的1, 例如:
- 21的二进制为
0001 0101
,20的二进制为0001 0100
& 运算之后为20 - 再将结果 20 与 19 进行 & 运算,即
0001 0100
&0001 0011
结果为 16 - 16 与 15 进行 & 运算,
0001 0000
&0000 1111
结果为0
public int[] countBits(int n) {
int[] result = new int[n+1];
int temp = 0;
int x = 0;
for(int i = 0; i<=n; ++i){
temp = 0;
x = i;
while(x>0){
++temp;
x = x & (x-1);
}
result[i] = temp;
}
return result;
}
评论
作者
猫颜
一花一世界,一叶一追寻
分享至