一、题目
给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例 1:
输入: 2
输出: [0,1,1]
示例 2:
输入: 5
输出: [0,1,1,2,1,2]
二、思路
总的思路是:写一个方法统计一个整数的二进制中 “1” 的数目,然后统计 0 ≤ i ≤ num 范围中的每个数字。
统计一个整数的二进制中 “1” 的数目有两种方法:
方法一:利用 Integer.toBinaryString(a)
利用 Integer.toBinaryString(a) 得到整数 a 的二进制字符串形式,统计字符串中字符 ‘1’ 的数目。代码如下:
public int count(int a){
String s = Integer.toBinaryString(a);
int length = 0;
for(int i = 0; i < s.length(); i++){
if(s.charAt(i) == '1')
length++;
}
return length;
}
方法二(来自题解):利用 a & (a - 1)
如果一个整数不为 0,那么这个整数至少有一位是 1。如果我们把这个整数减 1,那么原来处在整数最右边的 1 就会变为 0,且这个 1 后面的所有的 0 都会变成 1(如果最右边的 1 后面还有 0 的话),而其余的位不会受影响。如,1100 - 1 = 1011。我们发现减 1 的结果是把从最右边的一个 1 开始的所有位都取反了。这个时候再把原来的整数和减去 1 之后的结果做与运算,则原来整数从最右边的一个 1 开始的所有位都会变成 0。如,1100 & 1011 = 1000。
也就是说,a & (a - 1) 的结果,就是把整数 a 最右边一个 1 变成 0。那么一个整数的二进制有多少个 1,就可以进行多少次这样的操作。代码如下:
public int count(int a){
int length = 0;
while(a != 0){
++length;
a = a & (a - 1);
}
return length;
}
三、代码
class Solution {
public int[] countBits(int num) {
int[] res = new int[num + 1];
for(int i = 0; i <= num; i++){
res[i] = count(i);
}
return res;
}
public int count(int a){
int length = 0;
while(a != 0){
++length;
a = a & (a - 1);
}
return length;
}
}