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

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

5小时前

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. 累加目标区间内的合法方案数。

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


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

一:重新解读题目泰波那契数列是一个充满数学趣味的递推序列:从第3项开始,每个数均为前三个数的和(即Tₙ₊₃ = Tₙ + Tₙ₊₁ + Tₙ₊₂)。当给定整数n时,需要高效计算出第n项的值。面对此类递...

GESP2023年六级真题解析:动态规划解决小杨买饮料问题(洛谷3873)

GESP2023年六级真题解析:动态规划解决小杨买饮料问题(洛谷3873)

一、题目解读小杨买饮料是GESP 2023年六级认证考试中的一道经典动态规划题目,考察学生对背包问题的理解和应用能力。题目描述小杨需要购买n种饮料,每种饮料有特定的体积w和价格v,他要在不超过容量l的...

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

CSP-J方格取数题解|动态规划解法|洛谷P7074代码解析

一、题目解读题目要求在一个n×m的网格中,从左上角到右下角选择一条路径,路径上的数字可重复取用,求取数之和的最大值。路径限制为仅能向右或向下移动。需注意路径的灵活性与重复取数的可能性,传统单向动态规划...

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

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

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

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

LeetCode 120题三角形最小路径和最优解法:动态规划详解与代码实现

一、题目解读LeetCode 120题“三角形最小路径和”要求给定一个由数字组成的三角形,从顶部开始向下移动,每次可向左或向右移动一格,计算从顶至底的最小路径和。三角形以二维向量形式给出,每层元素数量...

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

洛谷P4551题解题报告:图论与Trie树优化异或路径问题的实战解析

一、题目解读洛谷P4551题要求在一个无向图中,寻找任意两点路径权值异或后的最大值。题目输入为图的边信息(点数n和n-1条边),每条边包含起点、终点及权值。需输出所有路径中权值异或的最大值。问题核心在...

发表评论

访客

看不清,换一张

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