题目:Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1’s in their binary representation and return them as an array.
通过率:58.4% 难度:medium
解法一:一开始看到这道题,想到的就是直接算出每一个数二进制表示中1的个数然后放进一个向量中,再输出,虽然复杂度比较高,但是容易理解,代码也容易实现,在LeetCode上也通过了。时间复杂度为O(nlogn),主要代码如下:
vector<int> countBits1(int num) {
vector<int> v;
for(int i = 0; i <= num; i++) {
int countOfOne = 0;
int ti = i;
while(ti != 0) {
if(ti % 2 == 1) {
countOfOne += 1;
}
ti /= 2;
}
v.push_back(countOfOne);
}
return v;
}
解法二:虽然第一种解法通过了测试,但是还是想寻求一种复杂度更低的算法,所以尝试写出多个数字的二进制,尝试寻求规律,见下表:
十进制 | 二进制 | 1的个数 |
---|---|---|
0 | 0000 | 0 |
1 | 0001 | 1 |
2 | 0010 | 1 |
3 | 0011 | 2 |
4 | 0100 | 1 |
5 | 0101 | 2 |
6 | 0110 | 2 |
7 | 0111 | 3 |
8 | 1000 | 1 |
9 | 1001 | 2 |
10 | 1010 | 2 |
11 | 1011 | 3 |
12 | 1100 | 2 |
13 | 1101 | 3 |
14 | 1110 | 3 |
15 | 1111 | 4 |
通过观察表格可以发现第2、3个数的二进制1的位数是第1、2个数的分别加1,第5到8个数的二进制1的位数是前4个数的二进制1的位数分别对应加1,依次类推,发现每对应一组和2的幂方相关,于是不需要分别算出每个数的二进制1的位数,可以根据前面得到的来推出后面的,时间复杂度是O(n),代码如下:
vector<int> countBits(int num) {
vector<int> v;
if(num == 0) {
v.push_back(0);
return v;
}
v.push_back(0);
v.push_back(1);
int tnum = 2, k = 1;
while(tnum <= num) {
int v_size = v.size();
for(int i = pow(2,k); i < pow(2,k+1); i++) {
v.push_back(v[i-v_size]+1);
tnum++;
if(tnum > num) {
break;
}
}
k++;
}
return v;
}