【剑指Offer(专项突破)】003. 前 n 个数字二进制中 1 的个数(Java实现) 详解析解

题目:

输入一个非负数n,请计算0到n之间每个数字的二进制形式中1的个数,并输出一个数组。例如,输入的n为4,由于0、1、2、3、4的二进制形式中1的个数为0、1、1、2、1,因此输出数组[0,1,1,2,1]

leetcode题目连接:https://leetcode.cn/problems/w3tCBm/ 

分析:

1、利用i&(i-1)计算

i变成i-1时,就是把最右边的1变成0, 同时把它右边的0都改为1。

 将i与i-1进行位与计算,可发现i&(i-1)的1总是比i的1数量少一个,因为在1*前的1都保留下来,1*及其之后的位与计算结果都为0,所以相差1个数量,差的正是1*

Java代码实现:

class Solution {
    public int[] countBits(int n) {
        int[] count = new int[n+1]; //定义数组,存放1的数量
        for(int i = 1; i <= n; i++){
            count[i] = count[i&(i-1)] + 1; //i中1的数量比i&(i-1)多1
        }
        return count;
    }
}

复杂度分析:

时间复杂度:O(n)

空间复杂度:O(1)

2、利用“i/2”计算

如果i是偶数,i/2的二进制形式只是把1移动一位,1的数量没变,例如4=100,2=010

如果i是奇数,i的二进制形式中1的数量总比i-1多1,因为i的最低位为1,多出来的一个1就是最低位的这个1,例如5=101,4=100

i/2=(i-1)/2,例如7/2=6/2=3

因此可以得到如下:

count[i] = count[i/1],i为偶数

count[i] = count[i-1] +1 = count[(i-1)/2] +1 = count[i/2] +1,i为偶数

合并为:

count[i] = count[i/2] + i%2

i/2可以用i>>1实现

i%2可以用i&1实现

如果i为奇数,最低位一定为1,i&1为1

如果i为偶数,最低位一定为0,i&1为0

i&1的作用等同于i%2,但是位运算比求余运算更高效

Java代码实现:

class Solution {
    public int[] countBits(int n) {
        int[] count = new int[n+1]; //定义数组,存放1的数量
        for(int i = 1; i <= n; i++){
            count[i] = count[i>>1] + (i&1);
        }
        return count;
    }
}

复杂度分析:

时间复杂度:O(n)

空间复杂度:O(1)

代码执行结果:

 

以上为个人做题笔记,很多是自己的理解,若有错误还请各位大佬指出~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值