Medium草稿★★★★★O(high) 時間 · O(high) 空間
Dynamic Programming
Patterns📈 線性 DP・Kadane
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

2466Count Ways to Build Good Strings1-D DPMedium1-D DP

給定 low, high, zero, one。每步可以在字串末尾加上 zero 個 ‘0’ 或 one 個 ‘1’。求長度在 [low, high] 之間的「好字串」有多少個,結果對 10^9 + 7 取模。

Example:

Input: low = 3, high = 3, zero = 1, one = 1 Output: 8

Intuition

TIP

Climbing Stairs 的變體 — 每步可以跳 zero 格或 one 格,求到達 [low, high] 範圍內任何位置的方法總數。

Approaches

1. Top-Down Memoization — O(high) / O(high)
  • Idea: 遞迴嘗試加 zero 或 one 個字元,記憶化
  • Time: O(high)
  • Space: O(high)
class Solution {
    fun countGoodStrings(low: Int, high: Int, zero: Int, one: Int): Int {
        val MOD = 1_000_000_007
        val memo = IntArray(high + 1) { -1 }
        fun dp(len: Int): Int {
            if (len > high) return 0
            if (memo[len] != -1) return memo[len]
            var res = if (len >= low) 1 else 0
            res = (res + dp(len + zero)) % MOD
            res = (res + dp(len + one)) % MOD
            memo[len] = res
            return res
        }
        return dp(0)
    }
}
⭐ 2. Bottom-Up DP — O(high) / O(high)
  • Idea: 從長度 0 到 high 逐步計算方法數,累加 [low, high] 範圍的答案
  • Time: O(high)
  • Space: O(high)
class Solution {
    fun countGoodStrings(low: Int, high: Int, zero: Int, one: Int): Int {
        val MOD = 1_000_000_007
        val dp = IntArray(high + 1)
        dp[0] = 1
        var ans = 0
        for (i in 1..high) {
            if (i >= zero) dp[i] = (dp[i] + dp[i - zero]) % MOD
            if (i >= one) dp[i] = (dp[i] + dp[i - one]) % MOD
            if (i in low..high) ans = (ans + dp[i]) % MOD
        }
        return ans
    }
}

🔑 Takeaways