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

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

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

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


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣第71题:用栈轻松解决Unix路径简化问题

力扣第71题:用栈轻松解决Unix路径简化问题

题目解读:在Unix风格的文件系统中,我们经常需要处理各种复杂的路径表示。给定一个绝对路径字符串,我们需要将其转换为最简化的规范路径。规范路径要求:路径始终以斜杠'/'开头;两个目录名...

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

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

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

力扣931题最小下降路径和解析 动态规划解法 LeetCode解题技巧

力扣931题最小下降路径和解析 动态规划解法 LeetCode解题技巧

一、题目解读力扣931题「Minimum Falling Path Sum」(最小下降路径和)要求在一个n x n的整数矩阵中,计算从顶部到底部的最小路径和。路径只能从每个位置向下或对角线移动(即向下...

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

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

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

洛谷P10472题解:利用栈求解最长有效括号

洛谷P10472题解:利用栈求解最长有效括号

一、题目解读洛谷P10472题要求计算给定字符串中最长有效括号的长度。有效括号指括号成对匹配(如"()[]{}"),子串需连续且内部嵌套正确。题目核心在于判断括号匹配的连续性,并找...

【2020蓝桥杯国赛C组】补给题解析:从Floyd到动态规划的高效解法

【2020蓝桥杯国赛C组】补给题解析:从Floyd到动态规划的高效解法

一、题目解读2020年蓝桥杯国赛C组“补给”题目要求:给定n个村庄坐标及最大补给距离D,需判断是否所有村庄均可从总部(村庄0)直接或间接到达,并计算访问所有村庄的最小路径(即旅行商问题TSP)。题目核...

发表评论

访客

看不清,换一张

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