zoukankan      html  css  js  c++  java
  • 338. 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.

    分析

    解法1 —— 直接求解

    当然最简单的做法就是遍历1-n,然后每个数字直接求其1的数字,这样复杂度变成了O(nlogn)
    这里就不给出具体代码了

    解法2 —— 动态规划问题

    我们可以把求某个数的1的个数,写出一个递推式
    定义re 为返回的数组, 则re[i] 就表示 i的二进制表示中的1的个数,我们把i的二进制表示分成两段,一段为前n - 1位, 另一段为 最右边一位。
    所以得到 re[i] = 前n-1位中的1的个数 + i%2
    而 前n-1位中1的个数可以用re数组的一个元素来表示, 也就是re[i >> 1]

    所以得到递归式子

    re[i] = re[i>>1] + i%2;

    然后循环 把re的所有项都得到。解法1之所以复杂度高是因为每次算1的个数的时候重复计算了前面的1的个数, 而动态规划里把前面数字的1的个数都记录下来,避免了重复计算, 但是这也要求需要一个数组来存储结果, 这是通过牺牲空间来换取时间的一种策略

    代码如下:

    class Solution {
    public:
        vector<int> countBits(int num) {
            vector <int> re(num+1, 0);
    
            for (int i = 0; i <= num; i++) {
                re[i] = re[i>>1] + i%2;
    
            }
    
            return re;        
        }
    };

    解法3

    这是最快的一种解法

    /* 
            Dynamic programming 
            Reoccurence relation:
                    dp[i] = dp[i & (i - 1)]] + 1 where i & (i - 1) erases right most bit
                    i & -i gives rightmost bit => i - (i & -i) erases rightmost bit
            O(n)
    */
    
    class Solution {
    public:
        vector<int> countBits(int num) {
            vector<int> dp(num + 1, 0);
    
            for (int i = 1; i < num + 1; ++i) {
                dp[i] = dp[i & (i - 1)] + 1;
            }
    
            return dp;
        }
    };
  • 相关阅读:
    管理业务IT从业人员转型生产管理1
    坐标系基准面地图投影系列介绍(二)_ 地理坐标系
    优化UVA11401(Triangle Counting)
    最小匹配hdu 3991 Harry Potter and the Present II
    解析xml——采用Jdom与dom4J方式写入xml文档
    解析xml——采用Jdom与dom4J方式读xml文档
    解析xml笔记总纲
    使用zoom.js 给博客园的图片添加点击图片放大功能
    Hello China V1.75版本运行截图
    基于visual c++之windows核心编程代码分析(26)实现文件关联
  • 原文地址:https://www.cnblogs.com/qq874455953/p/9901068.html
Copyright © 2011-2022 走看看