ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

codeforces-go 算法模板库实战解析:LeetCode 双周赛 142 Q1「相邻相同字母对数 + 1」的思维题解法与 Go 工程化测试

2026/10/5 6:39:06 拓冰建站 浏览量
codeforces-go 算法模板库实战解析:LeetCode 双周赛 142 Q1「相邻相同字母对数 + 1」的思维题解法与 Go 工程化测试 科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载本篇技术指南以 leetcode/biweekly/142/a/README.md 为骨架完整剖析灵茶山艾府灵神对力扣双周赛 142 第一题Find the Original Typed String I的题解相邻相同字母对的个数 1这一核心结论的推导过程、七种语言的代码实现以及该题解在 codeforces-go 仓库中以源码 用例文件 自动测试方式落地的工程实践。读完本文你将掌握这类重复按键恢复原串计数问题的通用解法并了解仓库中a.go / a.txt / a_test.go三件套如何通过 leetcode/testutil/leetcode.go 完成用例驱动验证。题目与背景Alice 的重复按键问题双周赛 142 的第一题是一道典型的简单思维题Alice 输入一个字符串时可能将其中某一个字母连续重复输入多次至多犯一次这样的错问最终得到的字符串word可能由多少种不同的原始字符串恢复而来。从仓库的 a_test.go 注释可以看到本题在力扣中的题号与入口// https://leetcode.cn/contest/biweekly-contest-142/problems/find-the-original-typed-string-i/ // https://leetcode.cn/problems/find-the-original-typed-string-i/本题数据规模没有压力核心难点在于想清楚计数规则而不是实现复杂度。核心思路每有一对相邻相同字母方案数就加一题解给出的结论极其简洁方案数 相邻相同字母对的个数 1其中的1对应完全不犯错的情况。逐步举例推导原题解的完整推理链原文档通过四个层次的例子把结论讲透这里完整复述并补充说明所有相邻字母都互不相同Alice 不可能犯重复一个字母的错原始字符串唯一方案数为1。有 1 对相邻相同字母例如abbAlice 一开始想输入的可能是abb未犯错ab把b多按了一次得到abb。共2种方案。有 2 对相邻相同字母又细分为两种形态连续堆叠型abbb原始串可能是abbb、abbb多按了一次、abb多按了两次共3种两处独立型aabb原始串可能是aabb、abba多按了一次、aabb多按了一次共3种。这里题解特别强调一个易错点一开始想输入的不可能是ab因为题目限定 Alice至多犯错一次——即只能重复输入一个字母多次aabb → ab等价于同时删除两个不同的字母超出了一次错误的范围。依此类推每多出一对相邻相同字母就多一种犯错方案即多删掉该对中的一个字母的恢复可能。因此方案数 相邻相同字母对数 1。这个推理对应一个直观理解一次重复输入错误只会产生一段连续的相同字母且这段连续字母中只删除其中某一个即可还原。因此每种可能的原始串与在哪一对相邻相同字母处删掉一个字母是一一对应的加上不犯错这一种。复杂度分析时间复杂度O(n)其中 n 是word的长度——只需从左到右扫描一遍字符串比较每个相邻字符对。空间复杂度O(1)——只用一个计数器不借助任何额外存储。七种语言的参考实现原文档完整代码原文档给出了 Python / Java / C / C / Go / JavaScript / Rust 七种实现核心逻辑完全一致ans从 1 起步每遇到一对相邻相同字符就ans。以下完整收录并给出关键行注释。Python3含一行写法class Solution: def possibleStringCount(self, word: str) - int: ans 1 for x, y in pairwise(word): if x y: ans 1 return ans一行写法利用布尔值可直接求和class Solution: def possibleStringCount(self, word: str) - int: return 1 sum(x y for x, y in pairwise(word))pairwise来自itertoolsPython 3.10恰好产出相邻字符对(word[i-1], word[i])。Javaclass Solution { public int possibleStringCount(String word) { int ans 1; for (int i 1; i word.length(); i) { if (word.charAt(i - 1) word.charAt(i)) { ans; } } return ans; } }Cclass Solution { public: int possibleStringCount(string word) { int ans 1; for (int i 1; i word.length(); i) { if (word[i - 1] word[i]) { ans; } } return ans; } };Cint possibleStringCount(char* word) { int ans 1; for (int i 1; word[i]; i) { if (word[i - 1] word[i]) { ans; } } return ans; }C 版直接以word[i]是否为\0作为循环终止条件省去strlen。Gofunc possibleStringCount(word string) int { ans : 1 for i : 1; i len(word); i { if word[i-1] word[i] { ans } } return ans }这是仓库 a.go 中的实际源码与题解文档逐字一致函数签名possibleStringCount(word string) int直接对应力扣题目函数原型。JavaScriptvar possibleStringCount function(word) { let ans 1; for (let i 1; i word.length; i) { if (word[i - 1] word[i]) { ans; } } return ans; };Rust含一行写法impl Solution { pub fn possible_string_count(word: String) - i32 { let s word.into_bytes(); let mut ans 1; for i in 1..s.len() { if s[i - 1] s[i] { ans 1; } } ans } }一行写法借助windows(2)扫描相邻窗口impl Solution { pub fn possible_string_count(word: String) - i32 { 1 word.into_bytes().windows(2).filter(|w| w[0] w[1]).count() as i32 } }仓库源码级印证用例驱动的 Go 工程实践codeforces-go 仓库为每道 LeetCode 题维护了**解法源码 用例文本 自动测试三件套**。以本题为例文件作用a.go解题函数possibleStringCount的实现a.txt纯文本测试用例输入与期望输出成对排列a_test.go测试入口调用测试框架执行用例用例文件 a.txt 的结构从 a.txt 可以看到每两行构成一组数据一行输入、一行期望输出abbcccc 5 abcd 1 aaaa 4逐组核对abbcccc相邻相同对为bb1 对与cccc3 对共 4 对方案数 4 1 5abcd无相邻相同对方案数 1aaaa3 对相邻相同方案数 3 1 4。三组用例恰好覆盖无错误、一处错误、连续堆叠三类形态与题解文档中的举例相互印证。测试框架RunLeetCodeFuncWithFile 的驱动原理a_test.go 的测试函数只有寥寥数行func Test_a(t *testing.T) { if err : testutil.RunLeetCodeFuncWithFile(t, possibleStringCount, a.txt, 0); err ! nil { t.Fatal(err) } }真正的工作在 leetcode/testutil/leetcode.go 的RunLeetCodeFuncWithFile中完成其核心流程从源码结构可以确认用os.ReadFile读取用例文件过滤空行后得到按行排列的数据通过reflect.TypeOf(f)反射目标函数的入参个数fNumIn与返回值个数fNumOut以fNumIn fNumOut行为一组切分用例对每个用例用parseRawArg按反射类型把文本参数还原为 Go 值字符串类型会去除首尾引号再调用fValue.Call(ins)执行被测试函数通过toRawString把实际返回值序列化为文本与期望输出比对失败时打印【答案错误 N】与输入信息支持targetCaseNum指定单个用例调试负数表示倒数第几个为 0 时跑全部用例在DebugTLE开启时还会用 goroutine time.After检测超时。这套反射驱动的机制意味着只要实现函数签名与力扣题目一致就能用仓库统一的用例格式输入/输出交替成对跑通本地验证无需手写断言。仓库如何批量生成双周赛测试leetcode/biweekly/142/README.md 记录了该场双周赛 Q1–Q4 的全部题解链接与视频讲解入口。而这类一场比赛一个目录、每题三件套的工程化布局来自模板目录 copypasta/template/leetcode/generator_test.go 的自动化生成逻辑TestBiweekly会通过GetBiweeklyContestID(0)获取下一场双周赛的 ID据此拼出leetcode/biweekly/{contestID}/目录随后调用GenLeetCodeTests配合LEETCODE_USERNAME_ZH/LEETCODE_PASSWORD_ZH环境变量抓取题目与样例自动生成a.go / a.txt / a_test.go三件套。这解释了为什么仓库中biweekly/142/a等目录结构高度统一所有题解都遵循README 题解 源码 用例 测试的同一套模板从双周赛 1 到 142 一以贯之。运行与验证方式在仓库根目录执行以下命令即可对本题的 Go 实现做本地验证go test ./leetcode/biweekly/142/a/ -vgo test会编译 a.go 与 a_test.go随后通过testutil.RunLeetCodeFuncWithFile读入 a.txt 中的三组用例并逐个断言。若想只看单个用例可将targetCaseNum从 0 改为对应序号负数表示倒数第几个测试框架会先跑指定用例、通过后再自动回归全部用例对应RunLeetCodeFuncWithExamples中targetCaseNum 0时递归调用自身的行为。对于整个双周赛目录也可以直接运行go test ./leetcode/biweekly/142/ -v从一道题看一类思维题这道 Q1 的价值在于把一次重复输入错误的恢复计数等价转化成了对连续相同字符段的简单统计避免了枚举所有可能的删字符位置。归纳起来这类相邻相同元素 计数的题目在仓库的题解体系中被反复使用同场双周赛的其余三题子树变化计数、旅行者最大得分、原串计数 II 的前缀和优化 DP则依次递进到 DFS 与动态规划完整题解汇总可继续阅读仓库内的 leetcode/SOLUTIONS.md灵神已分类的题解精选目录。一句话总结对于至多重复输入一个字母多次的恢复计数问题答案永远是「相邻相同字母对数 1」实现只需一遍扫描 O(n) 时间、O(1) 空间而在 codeforces-go 仓库中这道题连同用例与测试共同构成可复现、可验证的工程化模板即查即用。赞分享科学计算【免费下载链接】codeforces-go算法竞赛模板库 by 灵茶山艾府 项目地址https://gitcode.com/GitHub_Trending/co/codeforces-go点击查看免费下载相关推荐codeforces-go 算法模板仓库实战解析在链表中插入相邻节点最大公约数LeetCode 双周赛 110 B 题codeforces go 算法模板仓库实战解析在链表中插入相邻节点最大公约数LeetCode 双周赛 110 B 题 本篇技术指南围绕 LeetCode科学计算LeetCode「删除相邻近似相等字符」贪心解法codeforces-go 仓库的 Go 实现与自动化测试实践LeetCode「删除相邻近似相等字符」贪心解法codeforces go 仓库的 Go 实现与自动化测试实践 本文基于 codeforces go 仓库中科学计算codeforces-go 仓库实战解析力扣双周赛 150 Q1「好数之和」的线性遍历解法与工程化测试codeforces go 仓库实战解析力扣双周赛 150 Q1「好数之和」的线性遍历解法与工程化测试 本篇技术指南以开源算法竞赛模板库 codeforces科学计算上一篇QQ空间历史说说完整备份指南三步永久保存青春记忆下一篇英雄联盟回放视频制作终极指南League Director完全解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考