每日一题之前 n 个数字二进制中 1 的个数

目录

1.1 题目

1.1.1  题目        

1.1.2 示例

1.2 解题思想

 1.2.1 暴力破解

1.2.2 利用奇偶性的特点 

1.3 函数代码


1.1 题目

1.1.1  题目        

        给定一个非负整数 n ,请计算 0 到 n 之间的每个数字的二进制表示中 1 的个数,并输出一个数组。

1.1.2 示例

//示例1
/*
输入: n = 2
输出: [0,1,1]
解释: 
0 --> 0
1 --> 1
2 --> 10
*/
//示例2
/*
输入: n = 5
输出: [0,1,1,2,1,2]
解释:
0 --> 0
1 --> 1
2 --> 10
3 --> 11
4 --> 100
5 --> 101
*/

1.2 解题思想

 1.2.1 暴力破解

        从0到n进行遍历,可以通过一个函数f来计算当前数字i二进制位总共有几个1,利用Brian Kernighan 算法,可以在一定程度上进一步提升计算速度。Brian Kernighan算法思想:对于当前整数x,令x&=(x-1),记录计算的次数直到x为0。如果一个数y,y 的二进制表示中只有最高位是 1,其余都是 0,我们则称y是2的整数次幂,假设k=100...00,k-1=011...11,k&=(k-1),k=0,对于一个整数k1=011001011,可以看作是多个整数幂构成的每当对它k1&=k1-1,k1就会变为k1=011001010,不断的计算它运算的次数就可以得到结果

复杂度分析   

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)
class Solution {
    public int[] countBits(int n) {
        int[] bits = new int[n + 1];
        for (int i = 0; i <= n; i++) {
            bits[i] = countOnes(i);
        }
        return bits;
    }

    public int countOnes(int x) {
        int ones = 0;
        while (x > 0) {
            x &= (x - 1);
            ones++;
        }
        return ones;
    }
}

1.2.2 利用奇偶性的特点 

        从最低位开始对于bitcount[1]=1,bitcount[2]=1,bitcount[3]=2,bitcount[4]=1...,对于偶数k=1011..1100,k的最低位一定为0,当对k/2运算可以得到k/2=0101...110就是等同于向左移动一位(也可以写为k>>1),二进制位中1的总数没有变化,可以表示为bitcount[n]=bitcount[n/2]。对于奇数最低位一定为1,假设k=101...11,k>>1=0101...01,可以发现二进制位总数少1,可以表示为bitcount[n]=bitcount[n/2]+1。合并可以得到递推式为:bitcount[n]=bitcount[n>>1]+n&1。

复杂度分析        

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

1.3 函数代码

   public int[] countBits(int n) {
      int[] res = new int[n+1];
      res[0] = 0;
        for(int i = 1; i <= n; i++){
            res[i] = res[i>>1] + i % 2;
        }
      return res;
   }

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值