当前位置:首页 > 力扣 > LeetCode 2466题解:统计构造好字符串的方案数(动态规划+模运算)

LeetCode 2466题解:统计构造好字符串的方案数(动态规划+模运算)

5个月前 (07-14)

LeetCode 2466题解:统计构造好字符串的方案数(动态规划+模运算) 动态规划 字符串 取模运算 组合计数 力扣题解 第1张

一、题目解读

LeetCode 2466题要求统计在长度范围 [low, high] 内,由字符 '0' 和 '1' 构成的“好字符串”数量。好字符串定义为:每次可添加 zero 个 '0' 或 one 个 '1' 扩展,且最终长度在合法区间内。例如,当 low=2, high=3, zero=1, one=2 时,合法字符串包括 "011"、"110"、"000" 等,方案数为 5。题目难点在于高效计算符合约束条件的组合数。

二、解题思路

采用“动态规划+模运算”策略,核心思想是将问题拆解为子问题的组合:

1. 状态定义:使用动态规划数组 dp[i] 表示长度为 i 的好字符串方案数。

2. 转移方程:

○ 若 i >= zero,可在前 i-zero 长度字符串末尾添加 zero 个 '0',即 dp[i] += dp[i-zero];

○ 若 i >= one,可在末尾添加 one 个 '1',即 dp[i] += dp[i-one]。

3. 边界条件:空字符串(长度0)为一种合法方案,即 dp[0] = 1。

4. 累加结果:遍历 [low, high] 区间内的 dp[i] 值求和,并通过取模防止溢出。

三、解题步骤

1. 初始化:

○ 定义模数 MOD = 1e9 + 7,避免整数溢出。

○ 创建 dp 数组并初始化,dp[0] = 1(空字符串合法)。

2. 动态规划循环,遍历长度 i=1 到 high,对每个长度:

    若 i >= zero,将 dp[i-zero] 累加至 dp[i](可扩展 zero 个 '0')。

    若 i >= one,将 dp[i-one] 累加至 dp[i](可扩展 one 个 '1')。

    每次累加后取模,确保结果合法。

3. 统计答案:

○ 遍历 i=low 到 high,累加 dp[i] 至结果变量 result,并取模。

4. 返回结果:最终 result 即为方案总数。

四、代码及注释

class Solution {
public:
    int countGoodStrings(int low, int high, int zero, int one) {
        const int MOD = 1e9 + 7;          // 定义模数防止溢出
        vector<int> dp(high + 1, 0);       // 动态规划数组,初始化为0
        dp[0] = 1;                       // 空字符串为一种方案
        
        // 动态规划:计算每个长度的合法方案数
        for (int i = 1; i <= high; ++i) {
            // 如果可以在末尾添加zero个'0'
            if (i >= zero) {
                dp[i] = (dp[i] + dp[i - zero]) % MOD;  // 累加方案并取模
            }
            // 如果可以在末尾添加one个'1'
            if (i >= one) {
                dp[i] = (dp[i] + dp[i - one]) % MOD;  // 累加方案并取模
            }
        }
        
        // 累加[low, high]范围内的方案数
        int result = 0;
        for (int i = low; i <= high; ++i) {
            result = (result + dp[i]) % MOD;       // 累加并取模
        }
        
        return result;                             // 返回最终结果
    }
};

五、总结

本解法通过动态规划将大问题分解为子问题,利用模运算优化避免溢出,时间复杂度为 O(high),空间复杂度为 O(high)。关键点包括:

1. 明确状态转移方程,通过已有方案推导新方案;

2. 边界条件处理(空字符串作为起始状态);

3. 累加目标区间内的合法方案数。

算法简洁高效,适用于组合计数类问题的求解,是动态规划的经典应用案例。


原创内容 转载请注明出处

分享给朋友:

相关文章

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

题目解读‌斐波那契数列是一个经典的数学问题,在计算机科学中常被用作算法教学的入门案例。这个神奇的数列从0和1开始,后续每个数字都是前两个数字之和。题目要求我们计算第n个斐波那契数,看似简单的问题背后却...

2024年GESP五级武器强化(洛谷B4071)解题代码C++版

2024年GESP五级武器强化(洛谷B4071)解题代码C++版

一、题目解读    2024年GESP(青少年软件编程能力等级考试)五级中的“武器强化”(洛谷平台题目编号B4071)是一道典型的算法优化问题。题目要求通过合理...

NOIP 2008火柴棒等式题解(C++代码实现)  动态规划与枚举算法详解

NOIP 2008火柴棒等式题解(C++代码实现) 动态规划与枚举算法详解

一、题目解读火柴棒等式问题(NOIP 2008,洛谷P1149)要求使用给定数量的火柴棒,构造形如 A + B = C 的等式,其中A、B、C均为整数,且火柴棒总数恰好等于输入值。需统计符合条件的等式...

1999年NOIP提高组导弹拦截(洛谷P1020)解题思路与动态规划代码解析

1999年NOIP提高组导弹拦截(洛谷P1020)解题思路与动态规划代码解析

一、题目解读    1999年NOIP提高组“导弹拦截”问题(对应洛谷P1020)要求设计导弹拦截系统:给定一组导弹高度数据,需计算最少拦截系统数量,并求最多能...

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

一、题目解读洛谷P4999题要求处理给定区间 [L, R] 内数字的拆分与求和问题。每个数字需拆分为其各位数字之和,并计算区间内所有数字之和的累加结果。题目需考虑大数情况,并采用取模运算(MOD=1e...

LeetCode 2222题解析:高效统计"010"与"101"子序列数量的算法优化

LeetCode 2222题解析:高效统计"010"与"101"子序列数量的算法优化

一、题目解读题目要求计算给定字符串中包含"010"或"101"子序列的数量。关键难点在于高效遍历所有子序列,避免重复计算。传统暴力解法时间复杂度O(n^3)会超...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。