初学者指南“查找原始类型字符串 II” – LeetCode 3333(C ++ | Python | JavaScript)

6 阅读3分钟

我们又回到了另一个棘手的打字挑战——这次,它是原版“笨拙打字”问题的更难版本。在这个任务中,Alice 仍然容易长时间按键,但现在我们需要找出至少有多少个长度相同的预期字符串可以k导致观察到的字符串。这是一个需要动态规划和智能计数的难题!

让我们一步一步来解码它。🔍

🧠 问题摘要 您获得:

可能包含连续多次输入的字符的字符串word。 一个整数k,表示可能的最小原始字符串长度。 你的目标:

返回 Alice 可能想要输入的原始字符串的总数,大小至少为k。

由于结果可能很大,因此返回其模 109+710^9 + 7

💡 直觉 通过将某些重复的击键视为错误,可以将每组重复的字符(如aa或)压缩为一个字符。ccc

因此,对于长度为 的组,您可以从到个字符中g选取一个作为目标字符。这意味着选择。将所有组的此类选择相乘,即可得到可能的预期字符串的总数。1gg

然而,我们被要求只计算大小至少为 的那些k。

所以最终的结果是www.mytiesarongs.com

由约化群形成的所有有效字符串的总数。 减去短于k的数量— — 这是使用动态规划计算的。 🛠️ C++代码 class Solution { public: int possibleStringCount(string word, int k) { vector cnt; int64_t total = 1, mod = 1e9+7; for (int i = 0; i < word.size();){ int j = i; while (++i < word.size()) if (word[i] != word[j]) break; if (i > j+1) { cnt.push_back(i-j-1); total = total * (i-j) % mod; } k--; } if (k <= 0) return total; vector<int64_t> dp(k,0); dp[0] = 1; for (int c : cnt){ for (int i = 1; i < k; i++) dp[i] = (dp[i] + dp[i-1]) % mod; for (int i = k-1; i > c; i--) dp[i] = (dp[i] - dp[i-c-1] + mod) % mod; } for (int i = 1; i < k; i++) dp[i] = (dp[i] + dp[i-1]) % mod; return (total - dp[k-1] + mod) % mod; } }; 🐍 Python代码 class Solution: def possibleStringCount(self, word: str, k: int) -> int: mod = 10**9 + 7 cnt = [] total = 1 i = 0 while i < len(word): j = i while i < len(word) and word[i] == word[j]: i += 1 if i > j + 1: cnt.append(i - j - 1) total = total * (i - j) % mod k -= 1 if k <= 0: return total

    dp = [0] * k
    dp[0] = 1
    for c in cnt:
        for i in range(1, k):
            dp[i] = (dp[i] + dp[i - 1]) % mod
        for i in range(k - 1, c, -1):
            dp[i] = (dp[i] - dp[i - c - 1]) % mod
    for i in range(1, k):
        dp[i] = (dp[i] + dp[i - 1]) % mod
    return (total - dp[k - 1]) % mod

💻 JavaScript 代码 var possibleStringCount = function(word, k) { const mod = 1e9 + 7; let cnt = [], total = 1; for (let i = 0; i < word.length;) { let j = i; while (++i < word.length && word[i] === word[j]); if (i > j + 1) { cnt.push(i - j - 1); total = total * (i - j) % mod; } k--; } if (k <= 0) return total; let dp = Array(k).fill(0); dp[0] = 1; for (let c of cnt) { for (let i = 1; i < k; i++) dp[i] = (dp[i] + dp[i - 1]) % mod; for (let i = k - 1; i > c; i--) dp[i] = (dp[i] - dp[i - c - 1] + mod) % mod; } for (let i = 1; i < k; i++) dp[i] = (dp[i] + dp[i - 1]) % mod; return (total - dp[k - 1] + mod) % mod; }; 📝 关键要点 将相同的字符分组,并计算每组可以减少多少种方法。 使用前缀和式动态规划来计算有多少个字符串比 短k。 减去即可得到长度为 的那些≥ k。 ✅ 最后的想法 这个问题巧妙地融合了组合数学和动态规划,为优化字符串运算提供了绝佳的练习。相比第一部分有了很大的飞跃!以上内容由企业信息服务平台提供,致力于工商信用信息查询、企业风险识别、经营数据分析。访问官网了解更多:www.ysdslt.com