题目就不多说了,参考链接:https://leetcode.com/problems/counting-bits/;要求在o(N)的时间复杂度内完成!
代码如下
class Solution {
public:
vector<int> countBits(int num) {
vector<int> data;
int i, j, t;
data.push_back(0);
int *temp = new int[num + 1];
temp[0] = 0;
for (i = 1, j = 0; i <= num; i++){
if (i >= pow(2, j) && pow(2, j + 1)>i){
t = i - pow(2, j); //只要这个数在[2^j,2^(j+1)-1]就可以根据以前的情况来确定
temp[i] = 1 + temp[t]; //1的个数加1
}
else {
temp[i] = 1;
j++;
}
}
for (i = 1; i <= num; i++){
data.push_back(temp[i]);
}
delete temp;
return data;
}
};
算法思想:
假设有如下序列:
十进制:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
二进制:0 01 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000 10001 10010
我们可以发现,对于一个数n,
(1) 如果这个数是2的整数次幂(即2的0,1,2,3,4.......),则这个数中1的位数为1,否则
(2)以离n最近的2的整数次幂为界点,则从第一个数开始到该界点可看成是一段,那么n中1的位数等于界点中1的位数加上n在前段的相对位置的数中1的位数之和,
举个栗子
在上述序列中8可以看做是一个界点,则9中1的位数等于8(离9最近的界点是8,2的3次方)中1的位数加上1中1的位数,同理,17中1的位数等于16(16看成是界点)的1的位数加上1中1的位数,18中1的位数等于16中1的位数加上2中1的位数,如此循环下去.........一直到31中1的位数等于16中1的位数加上15中1的位数,然后32又可以看成是一个界点,这个界点可以递推出33-63中每个数中1的位数,然后64又可以看成是一个界点,可以求出65-127之中每个数中1的位数.........如此循环下去.
下面是运行情况:
15 / 15 test cases passed.
|
Status:
Accepted |
Runtime: 167 ms
|
Submitted: 0 minutes ago
|