LeetCode刷题|338比特位计数

今天的每日一题是一道与二进制有关的题目,也是我第一次做这样的题目。还是先看一下题目描述吧。

题目描述

在这里插入图片描述
LeetCode地址:比特位计数

我的解法

暴力解法第一人又开始表演了。这个题要求我们返回0-num之间所有数字的二进制表示的1的数量,返回值是一个数组。那么最直接的想法就是,遍历每一个数字,将数字转化为二进制,再遍历每一个二进制位的每一个元素,计算有多少个1,然后加入到一个数组中。最后返回整个数组。

class Solution:
    def countBits(self, num: int) -> List[int]:
        count = []
        for i in range(num+1):
            binary = bin(i).replace('0b','')
            t = 0
            for j in binary:
                if j=='1':
                    t = t+1
            count.append(t)
        return count

代码也比较简单,这里求二进制位是采用python内置的bin函数,其他都是一些常规操作。
我发现最近几天刷到的中等难度的题目,如果只是想通过的话并不是太难,但是如果想要取得比较好的效果就很麻烦了。而且这道题还有进阶,如果不用内置函数求二进制的话要怎么解决呢,看看官方解法吧。

官方解法

官方解法用到了一个小技巧,按位与运算(&)的一个性质是:对于任意整数 x,令 x=x &(x-1),该运算将 xx的二进制表示的最后一个 1 变成 0。因此,对 x 重复该操作,直到 x变成 0,则操作次数即为 x 的「一比特数」。

class Solution:
    def countBits(self, num: int) -> List[int]:
        def countOnes(x: int) -> int:
            ones = 0
            while x > 0:
                x &= (x - 1)
                ones += 1
            return ones
        
        bits = [countOnes(i) for i in range(num + 1)]
        return bits

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/counting-bits/solution/bi-te-wei-ji-shu-by-leetcode-solution-0t1i/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

countOnes函数计算一个数二进制位的1的个数,遍历每一个数调用countOnes就可以了。
另外官方还有几个动态规划的方法,因为我看不懂加还没学所以暂时不放上来了。

评论区解法-奇偶性

数字是奇数时,二进制数一定比上一个偶数的最后多一个1。当数字是偶数时,里面1的数量一定跟它的一半的数字里面个数1是一样的,因为偶数除2就是整体右移一位。

vector<int> countBits(int num) {
        vector<int> result(num+1);
        result[0] = 0;
        for(int i = 1; i <= num; i++)
        {
            if(i % 2 == 1)
            {
                result[i] = result[i-1] + 1;
            }
            else
            {
                result[i] = result[i/2];
            }
        }
        
        return result;
    }

作者:duadua
链接:https://leetcode-cn.com/problems/counting-bits/solution/hen-qing-xi-de-si-lu-by-duadua/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值