原题链接:
题目大意:
输入一个数字num,输出一个数组,表示从0到num的所有数字的二进制形式中,1的个数。
解题思路:
找规律。
0: [0]
1: [0,1+a[0]]
2: [0,1+a[0],1+a[0]]
3: [0,1+a[0],1+a[0],1+a[1]]
4: [0,1+a[0],1+a[0],1+a[1],1+a[0]]
5: [0,1+a[0],1+a[0],1+a[1],1+a[0],1+a[1]]
6: [0,1+a[0],1+a[0],1+a[1],1+a[0],1+a[1],1+a[2]]
...
用一个数组来模拟此规律即可。
- 设置start=1,为此次循环的起点,同时置index=0
- a[start+index] = a[index]+i
- index=start时,start+=index,开始下一循环
- 至index+start == num 为止。
AC代码如下:
public static int[] countBits(int num){
int[] bits = new int[num+1];
int start = 1,index=0;
bits[0] = 0;
while(start+index<=num){
bits[start+index] = 1+bits[index];
index++;
if(index == start){
start += index;
index = 0;
}
}
return bits;
}
复制代码
耗时3ms,rank 42.7%
在讨论区找到了更优秀的解法:
public int[] countBits(int num) {
int[] f = new int[num + 1];
for (int i=1; i<=num; i++)
f[i] = f[i >> 1] + (i & 1);
return f;
}
复制代码
充分利用位运算来进行解题,这才是真正的规律。