[力扣每日一题]338.比特位计数

[力扣每日一题]338.比特位计数

题目详情

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

进阶

​ 1.争取在线性时间O(n)内用一趟扫描做到;

​ 2.要求算法的空间复杂度为O(n);

​ 3.不使用任何内置函数

1.暴力解法

本题可以看做191题的进阶,暴力解法是基于191中的第二种解法

public class LCode338 {

    public static void main(String[] args) {
        int num = 5;
        System.out.println(Arrays.toString(countBits(num)));
    }

    private static int[] countBits(int num) {
        int[] result = new int[num + 1];

        for (int i = 0; i <= num; i++) {
            result[i] = countOne(i);
        }
        return result;
    }

    private static int countOne(int num) {
        int result = 0;
        while (num != 0) {
            num = num & (num - 1);
            result++;
        }
        return result;
    }
}
2.(官方题解)动态规划–最高有效位

首先,用【一比特数】表示二进制中的1的个数,用bits[i]来表示,当计算i的一比特数时:

  1. 找到k,使bits[i] = bits[k] + 1;
  2. 对于正整数i,如果可以知道最大正整数j,使得j <= i且j是2的整数次幂,则有bits[i] = bits[i - j] + 1(j最高位为1,其余位为0),其中j称为i的最高有效位,用highBit表示;
  3. 对于正整数j,当且仅当j&(j - 1) = 0时,j是2的整数次幂;
  4. 易得bits[0] = 0,故具体的代码思路为:
  • 当i & (i - 1) = 0时,说明i为2的整数次幂,此时令highBit=i(更新当前的最高有效位);
  • 从小到大遍历每个数,则有bits[i] = bits[i - highBit] + 1
public class LCode338 {

    public static void main(String[] args) {
        int num = 5;
        System.out.println(Arrays.toString(countBits(num)));
    }

    public static int[] countBits(int num) {
        int[] bits = new int[num + 1];
        int highBit = 0;
        for (int i = 1; i <= num; i++) {
            if ((i & (i - 1)) == 0) {
                highBit = i;
            }
            bits[i] = bits[i - highBit] + 1;
        }
        return bits;
    }
}

官方牛逼

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值