2466. 统计构造好字符串的方案数 - 力扣(LeetCode)


这个问题可以用**动态规划(DP)**来解决,思路如下:
思路
1. 定义 DP 数组
设 dp[i] 表示长度为 i 的好字符串的个数。
2. 状态转移方程
- 我们可以在
dp[i]的基础上添加zero个'0',得到dp[i + zero]。 - 或者在
dp[i]的基础上添加one个'1',得到dp[i + one]。
因此,状态转移方程为:dp[i]=dp[i−zero]+dp[i−one]
需要对 10^9 + 7 取模。
3. 初始化
dp[0] = 1,表示空字符串。
4. 目标
- 我们要求
low ≤ i ≤ high之间的所有dp[i]的总和。
代码实现
def countGoodStrings(low: int, high: int, zero: int, one: int) -> int:MOD = 10**9 + 7dp = [0] * (high + 1)dp[0] = 1 # 空字符串# 计算 dpfor i in range(1, high + 1):if i >= zero:dp[i] = (dp[i] + dp[i - zero]) % MODif i >= one:dp[i] = (dp[i] + dp[i - one]) % MOD# 计算 [low, high] 之间的总和return sum(dp[low: high + 1]) % MOD
复杂度分析
- 时间复杂度:O(high)。
- 空间复杂度:O(high)。
示例
输入
print(countGoodStrings(2, 3, 1, 2))
输出
5
解释
满足条件的字符串:
"00","11","01","10","001"。
优化
由于 dp[i] 只依赖于前面的 dp[i-zero] 和 dp[i-one],可以用一个变量存储 dp[low] 到 dp[high] 之间的和,减少不必要的计算:
def countGoodStrings(low: int, high: int, zero: int, one: int) -> int:MOD = 10**9 + 7dp = [1] + [0] * highresult = 0for i in range(1, high + 1):if i >= zero:dp[i] = (dp[i] + dp[i - zero]) % MODif i >= one:dp[i] = (dp[i] + dp[i - one]) % MODif i >= low:result = (result + dp[i]) % MOD # 直接求和return result
这样可以避免额外的 sum() 计算,使得代码更高效!🚀