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

    题目:意思是给出一个非负整数N,算出0到N的每一个数的二进制形式中方包含1的个数

    思路:题目说啦,时间复杂度要线性增长,空间复杂度为O(n),一开始我想着直接迭代每一个数,求出其二进制形式,统计一番不就完事了,看来现在不行了,而后实在没思路看了一位同仁的解法,感觉很不错,遂思之而后改之,大概思路是,把源数组中的数字做一个分组,分组的依据是根据2的次幂进行递进,2-4一组(base为2,边界为4),4-8一组(base为4,边界为8),8-16(base为8,边界为16)....每次对各个组内元素迭代,迭代完,以边界为base进行下一次迭代....直至N,为什么这么分组呢,是因为存在这样一个规律,即每一组内中元素(原数组第i个)的二进制形式包含1的个数(count_1)等于第i-base个元素的count_1加上1,表示为:res表示返回数组,有公式:     

              res[i] = res[i-base]+1 ;

    核心逻辑就这一行,具体代码如下:

    public int[] countBits(int num) {

      int[] res = new int[num + 1];
      res[0] = 0;

      int base = 1;
      while(base <= num){//以base作为迭代变量,
        int next = base <<1;//这么写乘号,据说是运行速度更快,然而并没有什么其他卵用。。。。
        for(int i = base;i<next && i<=num;i++){//每个base组内按规律做迭代
          res[i] = res[i-base]+1;
        }
          base = next;
      }
        return res;
    }

    思路2:还有一种思路是我大学学习我大电子专业核心基础课-数字电路的逻辑运算时发现的另外一个规律,一个数n与n-1做逻辑与运算,总是能把n的二进制最后一个1去掉,假设

    n=15,15(1111)&7(1110) = 1110,

    n=12,12(1100)&11(1011) = 1000,....

    这样是不是顿时有了思路,只要&运算到0,运算次数就是count_1,代码如下:

    public int[] countBits(int num) {
      int [] res = new int[num+1];
      int len = res.length;
      res[0] = 0;


      for(int i = 1;i<len;i++){
        int count = 0,j = i;
        while(j!=0){
          count++;
          j = j & (j-1);
        }
        res[i] = count;
      }
        return res;
    }

    运行情况来看,way1的runtime是2ms,way2的runtime是6ms,还是人家的办法效率高,不过我的这个容易理解一点。

    我曾经以为搞了软件,之前那些模电,数电,信号处理就没用了,其实有些规律,还是有一点用的。。。(ps:就不知量子物理以后有没有用到的时候,就算用到了,我也不会啊。。。)

  • 相关阅读:
    java项目路径获取
    String.getBytes()和new String()(string与byte[]的转换)
    Android生成一维码
    Android PullToRefresh (GridView 下拉刷新上拉加载)
    Android PullToRefresh (ListView GridView 下拉刷新) 使用详解
    Android 二维码扫描框 加四个角及中间横线自动下滑
    android 百度地图定位开发2
    android 百度地图定位开发1
    广播发送者&广播接收者介绍
    电脑配置 eclipse 环境变量
  • 原文地址:https://www.cnblogs.com/wujunjie/p/5673253.html
Copyright © 2011-2022 走看看