↓Skip to main content
  1. LeetCode/

LeetCode 338: Counting Bits

·2 mins· ·
LeetCode Easy Dynamic-Programming Bit-Manipulation
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: easy First Attempt: 2022-11-15

  • Submissions: Wrong Answer ×4 → Runtime Error → Accepted → Wrong Answer ×2 → Accepted

Approach
#

Shifting i right drops its lowest bit, so bits(i) = bits(i >> 1) + (i & 1), and i >> 1 < i is already known (Linear DP Template 1 with Bit Manipulation). Alternatively drop the highest bit: with offset the largest power of two not above i, bits(i) = bits(i - offset) + 1, updating offset when i is a power of two (i & (i - 1) == 0).

My Attempts
#

On 2022-11-15 I used the “drop the highest bit” form:

  • The first four updated the offset at every even number (if i % 2 == 0: count = i), although it should be the highest power of two: 6 got offset 6, so dp[6] = dp[0] + 1 = 1 instead of 2.
  • Testing powers of two with i & (i - 1) == 0 then hit ans[1] out of range for n = 0; a special case passed.
  • On 2022-11-27 another counting variant failed twice before passing.

Solution
#

class Solution:
    def countBits(self, n: int) -> List[int]:
        dp = [0] * (n + 1)
        for i in range(1, n + 1):
            dp[i] = dp[i >> 1] + (i & 1)
        return dp

Complexity
#

Time O(n), space O(n) (output).

Mistakes to Avoid
#

  • The highest-bit offset changes only at powers of two, not at every even number.
  • For n = 0 the array has one cell, so dp[1] cannot be set.

Interview Explanation
#

Shifting i right drops its lowest bit, giving a smaller, already computed number, so dp[i] is dp[i » 1] plus i’s lowest bit. Time O(n).

Related

LeetCode 1137: N-th Tribonacci Number
·2 mins
LeetCode Easy Math Dynamic-Programming Memoization
LeetCode 1137 note: like Fibonacci, roll three variables; watch the base values T0 = 0, T1 = T2 = 1 and the loop range
LeetCode 1018: Binary Prefix Divisible By 5
·1 min
LeetCode Easy Array Bit-Manipulation
LeetCode 1018 note: each new bit turns the prefix into x = 2x + bit, so keep only x mod 5 and the number never grows
LeetCode 1025: Divisor Game
·2 mins
LeetCode Easy Math Dynamic-Programming Brainteaser Game-Theory
LeetCode 1025 note: dp[i] holds when some divisor x of i makes dp[i - x] a loss; observing the pattern, the answer is simply whether n is even
LeetCode 868: Binary Gap
·2 mins
LeetCode Easy Bit-Manipulation
LeetCode 868 note: remember the last 1’s position and take the maximum distance at each new 1
LeetCode 832: Flipping an Image
·2 mins
LeetCode Easy Array Two-Pointers Bit-Manipulation Matrix
LeetCode 832 note: reverse each row and invert its bits, which two pointers can do at once
LeetCode 693: Binary Number with Alternating Bits
·1 min
LeetCode Easy Bit-Manipulation
LeetCode 693 note: alternating bits means the binary string has neither 00 nor 11; in bits, n ^ (n » 1) is all ones