↓快轉到主要內容
  1. LeetCode/

LeetCode 338: Counting Bits

·1 分鐘· ·
LeetCode Easy Dynamic-Programming Bit-Manipulation
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: easy 第一次嘗試:2022-11-15

  • 提交紀錄:Wrong Answer ×4 → Runtime Error → Accepted → Wrong Answer ×2 → Accepted

解題思路
#

i 右移一位就是去掉最低位,所以 bits(i) = bits(i >> 1) + (i & 1),i >> 1 < i 已經算過了(Linear DP 模板一,配合 Bit Manipulation)。另一種寫法是去掉最高位:offset 是不超過 i 的最大 2 的次方,bits(i) = bits(i - offset) + 1;i 是 2 的次方(i & (i - 1) == 0)時更新 offset。

我的嘗試
#

2022-11-15 用的是「去掉最高位」的寫法:

  • 前四版在每個偶數都更新 offset(if i % 2 == 0: count = i),但 offset 應該是最高位的 2 的次方:例如 6 的 offset 被設成 6,dp[6] = dp[0] + 1 = 1,答案 2。
  • 改成 i & (i - 1) == 0 判斷 2 的次方之後,n = 0 時 ans[1] 超出範圍;補上特例就 AC 了。
  • 2022-11-27 又換了一種計數寫法錯了兩次才 AC。

正確解法
#

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

複雜度
#

時間 O(n),空間 O(n)(輸出)。

要特別避免的錯誤
#

  • 最高位的 offset 只在 2 的次方時更新,不是每個偶數。
  • n = 0 時陣列只有一格,不能直接設 dp[1]。

面試口說整理
#

i 右移一位就是去掉最低位,那個數比 i 小、已經算過,所以 dp[i] 等於 dp[i » 1] 加上 i 的最低位。時間 O(n)。

相關文章

LeetCode 1137: N-th Tribonacci Number
·1 分鐘
LeetCode Easy Math Dynamic-Programming Memoization
LeetCode 1137 解題筆記:跟 Fibonacci 一樣,用三個變數滾動;小心 T0 = 0、T1 = T2 = 1 的起始值和迴圈範圍
LeetCode 1018: Binary Prefix Divisible By 5
·1 分鐘
LeetCode Easy Array Bit-Manipulation
LeetCode 1018 解題筆記:前綴每多一位就是 x = 2x + bit,只要保留 x mod 5,數字不會變大
LeetCode 1025: Divisor Game
·1 分鐘
LeetCode Easy Math Dynamic-Programming Brainteaser Game-Theory
LeetCode 1025 解題筆記:dp[i] = 存在 i 的因數 x 讓 dp[i - x] 是輸;觀察後答案就是 n 是偶數
LeetCode 868: Binary Gap
·1 分鐘
LeetCode Easy Bit-Manipulation
LeetCode 868 解題筆記:記錄上一個 1 的位置,每遇到新的 1 就算距離取最大值
LeetCode 832: Flipping an Image
·1 分鐘
LeetCode Easy Array Two-Pointers Bit-Manipulation Matrix
LeetCode 832 解題筆記:每一列先左右反轉再把 0、1 互換;可以用左右指針同時做
LeetCode 693: Binary Number with Alternating Bits
·1 分鐘
LeetCode Easy Bit-Manipulation
LeetCode 693 解題筆記:相鄰位元都不同,代表二進位字串裡沒有 00 也沒有 11;位元版本是 n ^ (n » 1) 全部是 1