好二进制字符串的数量
难度:
标签:
题目描述
代码结果
运行时间: 154 ms, 内存: 20.2 MB
// 题目思路:
// 这个题目要求找出所有满足特定条件的二进制字符串的数量。
// 条件为:字符串中没有连续的两个'0'。
// 使用Java Stream API我们可以简化一些操作,
// 但动态规划的核心思想仍然保持不变。
// 递推关系同样为:
// dp[i][0] = dp[i-1][1]
// dp[i][1] = dp[i-1][0] + dp[i-1][1]
// 初始化:dp[1][0] = 1, dp[1][1] = 1
import java.util.stream.IntStream;
public class Solution {
public int countGoodBinaryStrings(int n) {
if (n == 1) return 2;
int[][] dp = new int[n + 1][2];
dp[1][0] = 1;
dp[1][1] = 1;
IntStream.range(2, n + 1).forEach(i -> {
dp[i][0] = dp[i - 1][1];
dp[i][1] = dp[i - 1][0] + dp[i - 1][1];
});
return dp[n][0] + dp[n][1];
}
}
解释
方法:
此题解采用动态规划的方法来解决“好二进制字符串的数量”问题。定义 dp[i] 表示长度为 i 的二进制字符串中满足条件的字符串数量。初始条件下,dp[0] = 1 表示长度为0的字符串(空字符串)是有效的。对于每个长度 i (从1到maxLength),若长度 i 大于等于 oneGroup,则可以在长度为 i-oneGroup 的所有好二进制字符串后附加 oneGroup 个 '1',形成新的好二进制字符串。类似地,若长度 i 大于等于 zeroGroup,则可以在长度为 i-zeroGroup 的所有好二进制字符串后附加 zeroGroup 个 '0'。最终结果为从 minLength 到 maxLength 的所有 dp 值的和,由于可能出现大数,结果需要对 MOD 取模。
时间复杂度:
O(maxLength)
空间复杂度:
O(maxLength)
代码细节讲解
🦆
在定义 dp[i] 时,为什么可以假定它仅依赖于 i-oneGroup 和 i-zeroGroup 的值,而不需要其他的组合或更复杂的依赖关系?
▷🦆
当 oneGroup 和 zeroGroup 的值非常接近时,此动态规划解法对于重复计算的处理是如何优化的?
▷🦆
在题解中没有明确提到'好二进制字符串'的具体定义,它是如何影响 dp 数组更新规则的?
▷🦆
题解中提到需要对结果进行模运算(MOD = 10 ** 9 + 7),这里使用模运算的具体原因是什么?
▷