【力扣】338. 比特位计数

目录

1.题目描述:

2.解法一:Brian Kernighan 算法


1.题目描述:

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

示例 1:

输入:n = 2
输出:[0,1,1]
解释:
0 --> 0
1 --> 1
2 --> 10

2.解法一:Brian Kernighan 算法

Brian Kernighan算法介绍:

简单来说就是对一个整数二进制数的最后一个1进行操作,有两种表示方式:

第一种:n&(n-1) 可以将n二进制数的最后一个1变为0

如图,计算结果将7最后的一位1变成了0.

第二种:n&(~n+1) 可以得到n二进制最后一个1对应的值

如图,计算结果获得了7最后一个1对应的值“1”.

所以根据Brian Kernighan算法,我们可以每次循环都将n的最后一位变成0,直至n等于0结束循环;或者每次循环n减去获取到的最后一个1对应的值,直至n等于0。最后记录出循环的次数就是1的个数!

代码实现n&(n-1)

public int[] countBits(int n) {
    int[] res = new int[n+1];
    for (int i=0;i<=n;i++){
        res[i] = count(i);
    }
    return res;
}
public int count(int num){
    int times = 0;
    while(num!=0){
        num = num&(num-1);//每次将num的最后一个1变成0
        times ++;//记录变换的次数就是1的个数
    }
    return times;
}

代码实现n&(~n+1)

public int[] countBits(int n) {
    int[] res = new int[n+1];
    for (int i=0;i<=n;i++){
        res[i] = count(i);
    }
    return res;
}
public int count(int num){
    int times = 0;
    while(num!=0){
        num -= num&(~num+1);//只有这里修改了,其他和上面一样
        times ++;
    }
    return times;
}

3.解法二:找规律

对于二进制数我们可以找到以下规律:

当n为奇数时
0 -》 0
1 -》 1
2 -》 10
3 -》 11
4 -》 100
5 -》 101
count(n) == count(n-1)-1
当n为偶数时
1 -》 1
2 -》 10
4 -》 100
8 -》 1000
16 -》 10000
count(n) == count(n/2)

当n为奇数时,n中1的个数等于(n-1)中1的个数加1;当n为偶数时,n中1的个数等于n/2中1的个数。

通过这一规律我们可以得到这题的解法。

代码实现如下:

public static int[] countBits1(int n) {
    int[] res = new int[n+1];
    res[0] = 0;
    for (int i = 1;i <= n;i ++){
        if(i%2==1){//是奇数
            res[i] = res[i-1]+1;
        }else {//是偶数
            res[i] = res[i/2];
        }
    }
    return res;
}

ok!结束!

参考题解:

. - 力扣(LeetCode)

. - 力扣(LeetCode)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睆小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值