[LeetCode] Counting Bits 计数位
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 1:
Input: 2
Output: [0,1,1]
Example 2:
Input: 5
Output:[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.
Special thanks to @ syedee for adding this problem and creating all test cases.
这道题给我们一个整数n,然我们统计从0到n每个数的二进制写法的1的个数,存入一个一维数组中返回,题目中明确表示不希望我们一个数字一个数字,一位一位的傻算,而是希望我们找出规律,而且题目中也提示了我们注意 [2-3], [4-7], [8-15] 这些区间的规律,那么我们写出0到 15 的数的二进制和1的个数如下:
------------- ------------- ------------- -------------
我最先看出的规律是这样的,除去前两个数字0个1,从2开始,2和3,是 [21, 22) 区间的,值为1和2。而4到7属于 [22, 23) 区间的,值为 1,2,2,3,前半部分1和2和上一区间相同,2和3是上面的基础上每个数字加1。再看8到 15,属于 [23, 24) 区间的,同样满足上述规律,所以可以写出代码如下:
解法一:
class Solution {
public:
    vector<int> countBits(int num) {
        if (num == ) return {};
        vector<int> res{, };
        int k = , i = ;
        while (i <= num) {
            for (i = pow(, k - ); i < pow(, k); ++i) {
                if (i > num) break;
                int t = (pow(, k) - pow(, k - )) / ;
                if (i < pow(, k - ) + t) res.push_back(res[i - t]);
                else res.push_back(res[i - t] + );
            }
            ++k;
        }
        return res;
    }
};
下面来看一种投机取巧的方法,直接利用了 built-in 的函数 bitset 的 count 函数可以直接返回1的个数,题目中说了不提倡用这种方法,写出来只是多一种思路而已:
解法二:
class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> res;
        for (int i = ; i <= num; ++i) {
            res.push_back(bitset<>(i).count());
        }
        return res;
    }
};
下面这种方法相比第一种方法就要简洁很多了,这个规律找的更好,规律是,从1开始,遇到偶数时,其1的个数和该偶数除以2得到的数字的1的个数相同,遇到奇数时,其1的个数等于该奇数除以2得到的数字的1的个数再加1,参见代码如下:
解法三:
class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> res{};
        for (int i = ; i <= num; ++i) {
            if (i %  == ) res.push_back(res[i / ]);
            else res.push_back(res[i / ] + );
        }
        return res;
    }
};
下面这种方法就更加巧妙了,巧妙的利用了 i&(i - 1), 这个本来是用来判断一个数是否是2的指数的快捷方法,比如8,二进制位 1000, 那么 8&(8-1) 为0,只要为0就是2的指数, 那么我们现在来看一下0到 15 的数字和其对应的 i&(i - 1) 值:
i binary '' i&(i-) ----------------------- ----------------------- ----------------------- -----------------------
我们可以发现每个i值都是 i&(i-1) 对应的值加1,这样我们就可以写出代码如下:
解法四:
class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> res(num + , );
        for (int i = ; i <= num; ++i) {
            res[i] = res[i & (i - )] + ;
        }
        return res;
    }
};
参考资料:
https://leetcode.com/problems/counting-bits/
https://leetcode.com/discuss/92796/four-lines-c-time-o-n-space-o-1
https://leetcode.com/discuss/92694/my-408-ms-c-solution-using-bitset
https://leetcode.com/discuss/92698/my-448ms-c-easy-solution-o-n-time-and-o-n-space
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Counting Bits 计数位的更多相关文章
- LeetCode Counting Bits
		原题链接在这里:https://leetcode.com/problems/counting-bits/ 题目: Given a non negative integer number num. Fo ... 
- LeetCode——Counting Bits
		Question Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calcu ... 
- Leetcode之动态规划(DP)专题-338. 比特位计数(Counting Bits)
		Leetcode之动态规划(DP)专题-338. 比特位计数(Counting Bits) 给定一个非负整数 num.对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数 ... 
- 【LeetCode】338. Counting Bits (2 solutions)
		Counting Bits Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num ... 
- LN : leetcode 338 Counting Bits
		lc 338 Counting Bits 338 Counting Bits Given a non negative integer number num. For every numbers i ... 
- 2016.5.16——leetcode:Reverse Bits(超详细讲解)
		leetcode:Reverse Bits 本题目收获 移位(<< >>), 或(|),与(&)计算的妙用 题目: Reverse bits of a given 3 ... 
- Week 8 - 338.Counting Bits & 413. Arithmetic Slices
		338.Counting Bits - Medium Given a non negative integer number num. For every numbers i in the range ... 
- leetcode 上的Counting Bits  总结
		最近准备刷 leetcode 做到了一个关于位运算的题记下方法 int cunt = 0; while(temp) { temp = temp&(temp - 1); //把二进制最左边那 ... 
- leetcode 338. Counting Bits,剑指offer二进制中1的个数
		leetcode是求当前所有数的二进制中1的个数,剑指offer上是求某一个数二进制中1的个数 https://www.cnblogs.com/grandyang/p/5294255.html 第三种 ... 
随机推荐
- WebGIS中快速整合管理多源矢量服务以及服务权限控制的一种设计思路
			文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 在真实项目中,往往GIS服务数据源被其他多个信息中心或者第三方 ... 
- 剖析并利用Visual Studio Code在Mac上编译、调试c#程序
			0x00 前言 一周多以前的微软的Build大会上,微软发布了一个让很多人眼前一亮的工具,也是本文的主角——Visual Studio Code.很多使用Windows的朋友都很高兴,认为又多了一个很 ... 
- Mysql 中 show full processlist
			processlist命令的输出结果显示了有哪些线程在运行,可以帮助识别出有问题的查询语句,两种方式使用这个命令. 1. 进入MySQL/bin目录下输入mysqladmin processlist; ... 
- 微信JS-SDK坐标位置转换为百度地图坐标
			微信JS-SDK开发过程中,使用getLocation获取坐标位置,如何将微信获取的坐标直接应用到百度地图中,显示以下效果: 说明:红色图标是从微信转换过来的位置,蓝色图标是周边位置.首先从微信开发流 ... 
- 在浏览器标签显示网站logo图标
			在网站根目录下添加favicon.ico文件,并在网页添加如下代码: <link rel="bookmark" href="~/favicon.ico" ... 
- [下载]北京新版小学英语五年级上册mp3点读APP
			义务教育教科书小学英语五年级上册点读软件.根据2014年北京教改版教材编写,发音标准.实现点读功能.点到哪里读到哪里.哪里不会点哪里!北京教育科学研究院编写,北京出版社出版.ISBN:97872001 ... 
- C#开发微信门户及应用(8)-微信门户应用管理系统功能介绍
			最近对微信接口进行深入的研究,通过把底层接口一步步进行封装后,逐步升级到自动化配置.自动化应答,以及后台处理界面的优化和完善上,力求搭建一个较为完善.适用的微信门户应用管理系统. 微信门户应用管理系统 ... 
- α-β剪枝算法的java语言实现(非常实用)
			利用α-β剪枝算法,对下图所示的博弈树进行搜索,搜索得到根节点选择的走步,以及没有必要进行评估的节点,并求出给出在何处发生了剪枝,以及剪枝的类型(属于α剪枝还是β剪枝). 注:□表示MIN节点:○表示 ... 
- 怎么解决tomcat占用8080端口问题
			怎么解决tomcat占用8080端口问题 相信很多朋友都遇到过这样的问题吧,tomcat死机了,重启eclipse之后,发现 Several ports (8080, 8009) requir ... 
- SVNKit支持SSH连接
			SVNKit这个开源工具,用于Java语言访问SVN库,咋看的时候很方便,其实坑特别多.我在这里只想跟大家说一句,如果你还没有用过,请不要在生产环境使用这个东西了,兼容性问题搞死你(替换方案是直接用s ... 
