Leetcode __338. 比特位计数

问题描述

给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

示例 1:

输入: 2
输出: [0,1,1]
示例 2:

输入: 5
输出: [0,1,1,2,1,2]
进阶:

给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可以在线性时间O(n)内用一趟扫描做到吗?
要求算法的空间复杂度为O(n)。
你能进一步完善解法吗?要求在C++或任何其他语言中不使用任何内置函数(如 C++ 中的 __builtin_popcount)来执行此操作。

解题思路

数字每%2如果为0则最后一位就是0,不为0则该位上为1,不断数字/2,直到为0,记录1的个数

实现

class Solution {
    public int[] countBits(int num) {
      
        int[] res=new int[num+1];
        for(int i =0;i<=num;i++){
            int n = 0;
            int tem=i;
            while(tem>0){
                if(tem%2!=0){
                    n++;
                }
                tem=tem/2;
            }
            res[i]=n;
        }
        return res;
        
    }
}

其他思路

2,4,8时候,即2的幂的时候只有一个1,则3=2+1,就是2中1的个数加上1中1的个数,再如10=8+2,则8中1的个数为1,2中1的个数为1,最终为2个1

实现2

对于求解一个十进制数转化为二进制时里面1的个数,可以先看一下概况:

十进制数        二进制数        1的个数

1            1           1

2            10           1

3            11           2

4            100          1

5            101           2

6            110           2

7            111           3
1:问题归纳:用数组a[ i ] 表示 i 的二进制中1的个数。

2:递推关系式    a[n] = a[n/2]       n为偶数

a[n] = a[n-1] +1       n为奇数

3:初始化:a[0] = 0

把数分奇数和偶数来分别判断:
偶数:偶数 i 中1的个数跟i/2中1的个数是相同的
奇数:偶数+1,奇数最后一位一定是1

public class CountBits {
    public int[] countBits(int num) {
        int[] res=new int[num+1];//a[0] = 0
      int n = num%2==0?num:num-1;//把传进来的值固定为偶数,这样就能判断遍历的值,每一个的奇偶性(固定为奇数也可,这里的目标是知道用的每个数的奇偶)
      for(int i=1;i<=n;++i){
          res[i]=res[(i-1)/2]+1;//奇数
            i++;//加1,变偶数
            res[i]=res[i/2];//偶数
      }
      if(n<num){//如果开始传的是奇数,把最后一个加进来
          res[num]=res[(num-1)/2]+1;
      }
      return res;
    }

}

实现3

    public int[] countBits1(int num) {
        int[] res = new int[num+1];
        for(int i=1;i<=num;i++){
            res[i]=res[i&(i-1)]+1;
        }
        return res;
    }

对于: res[i]=res[i&(i-1)]+1
奇数:i&(i-1)=i-1(奇数到小于它的偶数,没有进位,只差1,也就是二进制的最后以为,1&0=0,即为它的偶数)
偶数:偶数&小于它的奇数,会有进位,当i&(i-1)时,剩下的就是它除了进位那个1以外的数,该数中的1的个数再加上进位的1就是最终它1的个数。

猜你喜欢

转载自blog.csdn.net/Growing_way/article/details/83243270