Likou brushing notes: 338. Bit count (four solutions, brute force method -> memory search method -> dynamic programming method, the fourth bit operation is strongly recommended, layer by layer, easy to understand)

topic:

338. Bit count
Given a non-negative integer num. For each number i in the range 0 ≤ i ≤ num, count the number of 1s in its binary number and return them as an array.

Example 1:

Input: 2
Output: [0,1,1]

Example 2:

Input: 5
Output: [0,1,1,2,1,2]

Advanced:

It is very easy to give a solution with a time complexity of O(n*sizeof(integer)). But can you do it with one scan in linear time O(n)?
——————————————————————————————————
The space complexity of the algorithm is required to be O(n).
——————————————————————————————————
Can you further improve the solution? It is required that no built-in functions (such as __builtin_popcount in C++) are used in C++ or any other language to perform this operation.

Method 1: Violence

Problem solution idea:
This should be the easiest way to think of, traverse each number from 0 to num, and count the number of 1s in the binary of each number.

Complexity:
Time complexity: O(N * sizeof(int))
Space complexity: O(1), the returned array is not included in the space complexity.

Problem solution python code:

class Solution:
    def countBits(self, num: int) -> List[int]:
        res = []
        for i in range(num + 1):
            res.append(bin(i).count("1"))
        return res

Method 2: Memory Search Method

Problem solution idea:
In the above violent solution, there are actually a lot of repeated calculations. For example, when i = 8, i = 4, 2, 1, 0 is required, and these values ​​have already been calculated, so you can Use memory search.

The so-called memory search is to save the calculation result every time the recursive function ends. In this case, if the same input is encountered the next time you recurse, you will directly query and return from the saved results without repeating the calculation again.

For example, when i=8, the situation of i=4 is required, and the situation of i=4 has been calculated before, so just return memo[4] directly.

Complexity:
Time complexity: O(N), because it is traversed once, each solution can be found from the previous memorized results.
Space complexity: O(N), using auxiliary space to save the result, the space result is O(N).

Problem solution python code:

class Solution(object):
    def countBits(self, num):
        self.memo = [0] * (num + 1)
        res = []
        for i in range(num + 1):
            res.append(self.count(i))
        return res
    
    def count(self, num):
        if num == 0:
            return 0
        if self.memo[num] != 0:
            return self.memo[num]
        if num % 2 == 1:
            res = self.count(num - 1) + 1
        else:
            res = self.count(num // 2)
        self.memo[num] = res
        return res

Method three: dynamic programming

In fact, many times, dynamic programming methods are optimized from memorized search. This problem can also be the same.

Method 2 In the process of memoizing search, we see that each time the recursive function is called, the recursive function will only run once, and it will be captured by memo and returned. In fact, you can remove the recursive function and check the result directly from the res array.

At the same time, the expression of the transfer equation is optimized as answer[i] = answer[i >> 1] + (i & 1).

So get the following dynamic programming scheme.

Complexity:
Time complexity: O(N)O(N), because it is traversed once.
Space complexity: O(1)O(1), the space occupied by the returned result is not included in the space complexity.

Problem solution python code:

class Solution:
    def countBits(self, num):
        res = [0] * (num + 1)
        for i in range(1, num + 1):
            res[i] = res[i >> 1] + (i & 1)
        return res

Author: fuxuemingzhu
link: https://leetcode-cn.com/problems/counting-bits/solution/yi-bu-bu-fen-xi-tui-dao-chu-dong-tai-gui-3yog/
Source: force LeetCode (LeetCode) https://leetcode-cn.com/problems/counting-bits/

Method 4: Bitwise operation (strongly recommended)

Problem solution idea:
You can change the way of thinking. When calculating the "number of bits" of i, if there is a "number of bits" of 0≤j<i, the "number of bits" of j is known, and i has only more binary representations than j If a 1, you can quickly get the "one-bit number" of i.

Let bits[i] denote the "number of bits" of ii, then the above relationship can be expressed as: [j]+1bits[i]=bits[j]+1.

For a positive integer x, if the largest positive integer y can be known such that y≤x and y is an integer power of 2, then only the highest bit in the binary representation of y is 1, and the rest are all 0. In this case, y is called x "Most Significant Bit" of. Let z=x−y, obviously 0≤z<x, then bits[x]=bits[z]+1.

In order to judge whether a positive integer is an integer power of 2, you can use the bitwise AND operation property mentioned in Method 1. If the positive integer y is an integer power of 2, only the highest bit in the binary representation of y is 1, and the rest are 0, so y&(y−1)=0. It can be seen that the positive integer y is an integer power of 2, if and only if y&(y−1)=0.

Obviously, the "number of bits" of 0 is 0. Use highBit to represent the current most significant bit, traverse each positive integer ii from 11 to num, and perform the following operations.

If i&(i−1)=0, set highBit=i, and update the current most significant bit.

i is 11 more than the "number of bits" of i-highBit. Since each number is traversed from small to large, when traversing to i, the "number of bits" of i-highBit is known. Let bits[i]=bits[ i−highBit]+1.

The resulting array bits is the answer.

Problem solution python code:

class Solution:
    def countBits(self, num: int) -> List[int]:
        bits = [0]
        highBit = 0
        for i in range(1, num + 1):
            if i & (i - 1) == 0:
                highBit = i
            bits.append(bits[i - highBit] + 1)
        return bits

Author: LeetCode-Solution
Links: https://leetcode-cn.com/problems/counting-bits/solution/bi-te-wei-ji-shu-by-leetcode-solution-0t1i/
Source: stay button (LeetCode) https://leetcode-cn.com/problems/counting-bits/

Guess you like

Origin blog.csdn.net/weixin_44414948/article/details/114323843