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)的时间复杂度,但是也接近了一些。抱着试试看的态度提交了一下。好吧。。。。。过了。
代码:
虽然提交过了但是心里总有一些不安的感觉,因为题目要求是O(n)的复杂度,经过看提供的答案代码看到了一个很棒的解法:
代码:
这次是真的O(n)的时间复杂度,分析代码可以总结出原理:如果n是偶数则1的个数等于n/2的中1的个数,因为n是由n/2左移一位得到的,而左移不会增加1的个数,如果n是奇数则1的个数等于n/2中1的个数加一,因为n是由n/2左移一位加一。为了代码的简洁性就写成了如上形式。不得不说这个方法太巧了!良辰服辣~~
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左移一位加一。为了代码的简洁性就写成了如上形式。不得不说这个方法太巧了!良辰服辣~~
相关文章推荐
- 【leetcode】Array——Best Time to Buy and Sell Stock I/II/III
- java中静态代码块的用法 static用法详解
- LeetCode之338—-Counting Bits
- Handle类的用法
- 协程
- UVALive 4256 Salesmen 【简单dp】
- 利用TouchesBegan解决页面内 触摸 某个视图以外的处理的情况
- 数组元素的赋值和遍历数组
- 数据统计
- Linux 版本查询
- 定位详解、层级、滤镜遮罩笔记
- 收到用980C币在C商城买的CSDN徽标保温杯
- 连接池技术BoneCP
- Android设计模式之原型模式
- 公司间采购的后台配置备忘录
- 质数因子
- 基于图的推荐算法——《推荐系统实践》
- Android中从ImageView中取出图片bitmap注意事项
- BZOJ 1806 IOI2007 Miners 矿工配餐 动态规划
- Java线程总结