LeetCode#338 Counting Bits题解(C++版)

题干

这里写图片描述

原题网址:
https://leetcode.com/problems/counting-bits/description/

题干解析

给你一个非负整数num,要你返回一个向量,这个向量的数据代表在[0, num]中每个数的二进制写法中“1”的个数。

知识点

逻辑

难度

中等

解题思路

这道题用暴力解法可以说是非常简单的了,但是题干要求,不能用暴力解法,要让时间复杂度和空间复杂度都是O(n),这就需要想一种更为高效的算法。其实我的解法有点像“找规律”,通过列出0-16的二进制数的“1”的个数{0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4},我们可以发现以下规律:其实大于等于2的k次方、小于2的k+1次方之间的二进制数的“1”的个数,正好是大于等于0、小于2的k次方的数每个数对应加一得来,比如:当k等于1时,2的k次方等于2,2的k+1次方等于4,那么[2, 4)中(即2和3)的二进制数的“1”的个数是{1,2},[0, 2)中(即0和1)的二进制数的“1”的个数是{0,1},也就是{0,1}的中的两项各加1即可得{1,2}。发现这个规律之后我们就可以愉快地在时间复杂度和空间复杂度为O(n)的限制下得到我们要的解了。

代码

class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> ans;
        int index = 0;
        for (int i = 0; i <= num; i++) {
            if (i == 0) {
                ans.push_back(0);
                continue;
            }
            if (i == pow(2, index)) {
                index++;
            }
            ans.push_back(1 + ans[i - pow(2, index - 1)]);
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值