给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例1:
输入: 2
输出: [0,1,1]
示例2:
输入: 5
输出: [0,1,1,2,1,2]
进阶:
看到题目的时候,不知道您的脑海里是不是会有一个想法,总感觉后面一个数的结果和前面的数的结果冥冥之中会有点联系。当计算一个数值的 1 的个数的时候,需要先知道比它小的最大的 2 的 N 次方的值。(比如:9 = 2 ^ 3 + 1,5 = 2 ^ 2 = 1 。。。)然后我们用当前的数值减去比它小的最大的 2 的 N 次方的值。用剩余的值的 1 的个数 + 1 。
这边用到了动态规划的思想,比较难找规律的就是使用靠近当前数值的 2 ^ N 次方加上剩余数值对应的 1 的个数。其中 2 ^ N 次方的数值只有一个 1。上图中绿色表格中个数相加的时候,前面的 1 表示的是 2 ^ N 次方里面只有一个 1。后面的数值是用当前数值减去最大的 2 ^ N 的差值对应的 1 的数量。
class Solution {
public int[] countBits(int num) {
//用来计算结果,因为 int 类型默认值是 0 ,所以第一位就默认赋值了
int[] retResult = new int[num + 1];
//用来计算当前 2 的 n 次方最高位
int highBit = 0;
for(int i=1;i<=num;i++){
//表示当前的数是 2 的 i 次方
if((i & (i -1)) == 0){
highBit = i;
retResult[i] = 1;
}else{
retResult[i] = retResult[i - highBit] + 1;
}
}
return retResult;
}
}
func countBits(num int) []int {
//用来计算结果,因为 int 类型默认值是 0 ,所以第一位就默认赋值了
retResult := make([]int, num + 1)
//用来计算当前 2 的 n 次方最高位
highBit := 0
for i:=1;i<=num;i++ {
//表示当前的数是 2 的 i 次方
if (i & (i -1)) == 0 {
highBit = i
retResult[i] = 1
}else{
retResult[i] = retResult[i - highBit] + 1
}
}
return retResult
}