uacs2024

导航

leetcode 2466. 统计构造好字符串的方案数

2466. 统计构造好字符串的方案数

没写出来🤡

题解

法一:记忆化搜索

class Solution {
public:
    // 计算在[low, high]范围内,满足'0'的数量不超过zero,'1'的数量不超过one的字符串数量
    int countGoodStrings(int low, int high, int zero, int one) {
        // MOD用于结果取模,防止整数溢出,这里取的是10^9 + 7
        const int MOD = 1'000'000'007;
        
        // 使用一个记忆化数组memo来存储已经计算过的结果,初始化为-1表示未计算
        vector<int> memo(high+1,-1); // 数组大小为high+1,因为i的范围是从0到high

        // 定义一个dfs函数(递归函数),用于计算满足条件的字符串数量
        // 使用lambda表达式和递归函数自身引用(&&dfs)实现递归记忆化搜索
        auto dfs = [&](auto &&dfs,int i) -> int{
            // 如果i小于0,说明当前字符串不满足条件(长度小于0),返回0
            if(i < 0)  return 0;
            // 如果i等于0,说明当前字符串为空字符串,满足条件,返回1
            if(i == 0)  return 1;
            // 尝试从memo中获取已经计算过的结果
            int &res = memo[i];
            // 如果res不等于-1,说明已经计算过,直接返回结果
            if(res != -1)  return res;
            // 递归计算以'0'结尾的字符串数量(减去zero)和以'1'结尾的字符串数量(减去one)
            // 并取模防止溢出,将结果存入memo并返回
            return res = (dfs(dfs,i - zero) + dfs(dfs,i - one)) % MOD;
        };

        // 初始化结果变量
        int res = 0;
        // 遍历low到high之间的每个数字,计算每个数字对应的满足条件的字符串数量并累加
        for(int i = low;i <= high;++i){
            res = (res + dfs(dfs,i)) % MOD;
        }
        // 返回最终结果
        return res;
    }
};

法二:递推

class Solution {
public:
    int countGoodStrings(int low, int high, int zero, int one) {
        const int MOD = 1'000'000'007;
        int res = 0;
        vector<int> dp(high+1);//dp[i] 表示构造长为 i 的字符串的方案数
        dp[0] = 1;
        for(int i = 1;i <= high;++i){
            if(i >= zero)  dp[i] = dp[i-zero];
            if(i >= one)  dp[i] = (dp[i] + dp[i-one]) % MOD;
            if(i >= low)  res = (res + dp[i]) % MOD;
        }
        return res;
    }
};

法三:递推优化

class Solution {
public:
    int countGoodStrings(int low, int high, int zero, int one) {
        int g = gcd(zero, one);
        low = (low - 1) / g + 1;
        high /= g;
        zero /= g;
        one /= g;

        const int MOD = 1'000'000'007;
        int res = 0;
        vector<int> dp(high+1);//dp[i] 表示构造长为 i 的字符串的方案数
        dp[0] = 1;
        for(int i = 1;i <= high;++i){
            if(i >= zero)  dp[i] = dp[i-zero];
            if(i >= one)  dp[i] = (dp[i] + dp[i-one]) % MOD;
            if(i >= low)  res = (res + dp[i]) % MOD;
        }
        return res;
    }
};

 

posted on 2024-12-28 20:46  ᶜʸᵃⁿ  阅读(51)  评论(0)    收藏  举报