leetcode笔记:Counting Bits

一. 题目描述

Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1’s in their binary representation and return them as an array.

Example:

For num = 5 you should return [0,1,1,2,1,2].

Follow up:

It is very easy to come up with a solution with run time O(n*sizeof(integer)). But can you do it in linear time O(n) /possibly in a single pass?

Space complexity should be O(n).

Can you do it like a boss? Do it without using any builtin function like __builtin_popcount in c++ or in any other language.

Hint:

You should make use of what you have produced already.

Divide the numbers in ranges like [2-3], [4-7], [8-15] and so on. And try to generate new range from previous.

Or does the odd/even status of the number help you in calculating the number of 1s?

二. 题目分析

题目大意是,给定一个非负整数num,对于每一个满足0 ≤ i ≤ num的数字i,计算这些数字的二进制表示中1的个数,并以数组vector的形式返回。

题目还给出了一系列提示:

很容易想到运行时间为:O(n*sizeof(integer)) 的解法。但你可以用线性时间:O(n)的一趟算法完成吗?空间复杂度应当为:O(n)

你可以像老板那样?不要使用任何内建函数(比如C++的__builtin_popcount)。

提示:

你应该利用已经得到的结果。

将数字拆分为诸如 [2-3], [4-7], [8-15] 之类的范围。并且尝试根据已经生成的范围产生新的范围。

也许数字的奇偶性可以帮助你计算1的个数?

从题目中给出的诸多提示,加上手写实例,容易发现一些规律,并得到多种方法,这里只列出两种位运算的解决方法。

方法一:

0   0000
1   0001
2   0010 // 左移一位,发现位数和(2/2 = 1)一致
3   0011 // 左移一位,发现位数和(2/2 = 1)一致,只是3为奇数,需要比1多1个1
4   0100
5   0101
6   0110
7   0111
8   1000 // 左移一位,发现位数和(8/2 = 4)一致
9   1001 // 左移一位,发现位数和(9/2 = 4)一致,只是9为奇数,需要比4多1个1
10  1010
11  1011
12  1100
13  1101
14  1110 // 左移一位,发现位数和(14/2 = 7)一致
15  1111 // 左移一位,发现位数和(15/2 = 7)一致,只是15为奇数,需要比7多1个1

根据以上实例,设F[n]表示正整数n的二进制个数,则可得到以下方程:

F[n] = F[n / 2] + F[n] & 1,根据这个方程,只需遍历一次0 ~ num的整数,即可得到各整数的二进制表示中含1的个数。

方法二:

0   0000
1   0001
2   0010
3   0011 // 对于非2的幂次数n,其二进制表示中1的个数比(n & (n - 1))多一个
4   0100
5   0101
6   0110
7   0111
8   1000 // 对于2的幂次数n,(n & (n - 1)) = 0,同样满足二进制表示中1的个数比(n & (n - 1))多一个
9   1001
10  1010
11  1011
12  1100
13  1101
14  1110
15  1111

该规律较难找出,可得到以下方程:F[n] = F[n & (n - 1)] + 1

三. 示例代码

// C++,方法一
class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> result;
        if (num < 0) return result;
        result.push_back(0);
        for (int i = 1; i <= num; ++i)
        {
            result.push_back(result[i >> 1] + (i & 1));
        }
        return result;
    }
};
# Python,方法一
class Solution(object):
    def countBits(self, num):
        """
        :type num: int
        :rtpye: List[int]
        """
        result = [0]
        for i in range(1, num + 1):
            result += result[i >> 1] + (i & 1),
        return result
// C++,方法二
class Solution {
public:
    vector<int> countBits(int num) {
        vector<int> result;
        if (num < 0) return result;
        result.push_back(0);
        for (int i = 1; i <= num; ++i)
        {
            result.push_back(result[i & (i - 1)] + 1);
        }
        return result;
    }
};
# Python,方法二
class Solution(object):
    def countBits(self, num):
        """
        :type num: int
        :rtype: List[int]
        """
        result = [0]
        for i in range(1, num + 1):
            result += result[i & (i - 1)] + 1,
        return result

四. 小结

最近项目组中期检查,耗费了不少时间,算法也没之前写的多了,思想容易迟钝。

时间: 2024-12-24 21:44:29

leetcode笔记:Counting Bits的相关文章

leetCode 338. Counting Bits | Dynamic Programming | Medium

338. Counting Bits Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Example:For num = 5 you should return [0,1,1,2,1,2]. 题目大意

【Leetcode】Counting Bits

题目链接:https://leetcode.com/problems/counting-bits/ 题目: Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Example: For num = 5 y

Leetcode 338 – Counting Bits

解法三种: Sln 1. 笨办法,移位.时间复杂度太高,基本就是O(n * sizesof(int)).Sln 2. 利用一个小技巧,偶数除二,在其另外一个乘数左移 1bit而得:奇数在前所得上加1Sln 3. Hamming Weight; 利弊: Sln 1不考虑,复杂度过高.相对来说Sln 2要较Sln 3简单,但是仅仅刷个算法题并没什么特别大的用处,还要考虑一下实际的应用场景.如果我们使用Sln 2,则如果要随机取一个数的二进制1 的个数,需要一个很大的查找表.Sln 3则是随时可用.

leetcode 338. Counting Bits,剑指offer二进制中1的个数

leetcode是求当前所有数的二进制中1的个数,剑指offer上是求某一个数二进制中1的个数 https://www.cnblogs.com/grandyang/p/5294255.html 第三种方法,利用奇偶性找规律 class Solution { public: vector<int> countBits(int num) { vector<int> result{0}; for(int i = 1;i <= num;i++){ if(i % 2 == 0) res

LeetCode 338. Counting Bits

Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Example:For num = 5 you should return [0,1,1,2,1,2]. Follow up: It is very e

LeetCode Q338 Counting Bits(Medium)

原题: Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Follow up: It is very easy to come up with a solution with run time O(n*

【LeetCode】Counting Bits(338)

1. Description Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Example: For num = 5 you should return [0,1,1,2,1,2]. 2. Answ

leetcode(1)--338.Counting Bits

LeetCode 338. Counting Bits Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Example: For num = 5 you should return [0,1,1,2,

[LeetCode][Java][JavaScript]Counting Bits

Counting Bits Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Example:For num = 5 you should return [0,1,1,2,1,2]. Follow up

【LeetCode】338. Counting Bits (2 solutions)

Counting Bits Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num calculate the number of 1's in their binary representation and return them as an array. Example:For num = 5 you should return [0,1,1,2,1,2]. Follow up