剑指Offer Ⅱ 003.二进制加法(力扣剑指Offer专项突击版——整数_3)

7 篇文章 0 订阅
4 篇文章 0 订阅
该博客讨论了如何计算0到给定非负整数n之间每个数字的二进制表示中1的个数。提供了两种解决方案:一种是直接计算每个数的二进制位数,时间复杂度为n*logn;另一种是采用动归思路,通过找到每个数的最低设置位来优化,达到线性时间复杂度。
摘要由CSDN通过智能技术生成

题目

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

示例 1:

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

题解

  • 题解一
    本体最直观的想法是,求每个数的二进制位个数,如下:`
 int count_1(int n)
    {
    int index = 1, res = 0;
        while (n > 0)
        {
        	//将n的最后一位1置0
            n &= (n - 1);
            res++;
        }
        return res;
    }

    vector<int> countBits(int n) {
        vector<int> res(n+1);
        for(int i = 0; i <= n; ++i)
            res[i] = count_1(i);
        return res;
    }

时间复杂度n*logn

  • 题解二 动归思路,参考力扣官方题解
    // leecode官方题解 最低设置位
    // 最低设置位定义为整数x的最低为1的位置 如10(1010)的最低设置位为2
    // 令y = x & (x - 1),则y变为1000,相当于将x的最低设置位置0
    // 可以发现 x的比特位比y大一,且x > y,由此推出等式 bits[i] = bits[i & (i - 1)] + 1;
vector<int> countBits(int n) {
       
        vector<int> bits(n + 1);
        for (int i = 1; i <= n; i++) {
            bits[i] = bits[i & (i - 1)] + 1;
        }
        return bits;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值