您的位置:首页 > 其它

LeetCode之338—-Counting Bits

2016-03-26 15:31 435 查看
最近上算法课上的有点心塞,所以感觉应该刷刷题来见见世面了,所以选择了LeetCode来做一点题目。

LeetCode之338:

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.

Example:

For num = 5 you should return [0,1,1,2,1,2].

Follow up:
It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?
Space complexity should be O(n).
Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.
题目大意:

给定数字num, 计算i在 0 <= i <= num 之间的所有数字二进制表示形式中1的数量,以数组的形式返回结果(时间复杂度要求在O(n),空间复杂度要求在O(n))

思路:

拿到题目自然而然能够想到第一个思路:可以通过位运算找出每一个数字中1的个数,然后存入一个vector中,但是这样做的话每个数字的循环次数最坏是32次,这样的话可能会超时,但是可以达到目的。在此基础上再加以改进可以得到第二个思路:每个数字转化为二进制之后都是在n – 1的基础之后上加1,所以可以让n & (n – 1)消去n中的1,直至所有的1消失。这样每个数字的移位次数只有1的个数次。虽然没有达到O(n)的时间复杂度,但是也接近了一些。抱着试试看的态度提交了一下。好吧。。。。。过了。

代码:

#include <iostream>
#include <cstdlib>
#include <vector>

class Solution {

public:
std::vector<int> countBits(int num) {
int count, tmp;
for (int i = 0; i <= num; ++i) {
for (count = 0, tmp = i; tmp; ++count) {
tmp = tmp & (tmp - 1);
}
v.push_back(count);
}

return v;
}

private:
std::vector<int> v;

};


虽然提交过了但是心里总有一些不安的感觉,因为题目要求是O(n)的复杂度,经过看提供的答案代码看到了一个很棒的解法:

代码:

vector<int> countBits(int num) {

vector<int> rst(num + 1);

rst[0] = 0;

for (int i = 1; i <= num; i++)

rst[i] = rst[i >> 1] + (i & 1);

return rst;
}

  这次是真的O(n)的时间复杂度,分析代码可以总结出原理:如果n是偶数则1的个数等于n/2的中1的个数,因为n是由n/2左移一位得到的,而左移不会增加1的个数,如果n是奇数则1的个数等于n/2中1的个数加一,因为n是由n/2左移一位加一。为了代码的简洁性就写成了如上形式。不得不说这个方法太巧了!良辰服辣~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: