python-leetcode-统计构造好字符串的方案数
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 + 7
dp = [0] * (high + 1)
dp[0] = 1 # 空字符串
# 计算 dp
for i in range(1, high + 1):
if i >= zero:
dp[i] = (dp[i] + dp[i - zero]) % MOD
if 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 + 7
dp = [1] + [0] * high
result = 0
for i in range(1, high + 1):
if i >= zero:
dp[i] = (dp[i] + dp[i - zero]) % MOD
if i >= one:
dp[i] = (dp[i] + dp[i - one]) % MOD
if i >= low:
result = (result + dp[i]) % MOD # 直接求和
return result
这样可以避免额外的 sum()
计算,使得代码更高效!🚀