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() 计算,使得代码更高效!🚀
267

被折叠的 条评论
为什么被折叠?



