多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

LeetCode-Go 题解:1684. Count the Number of Consistent Strings(一致字符串计数)

LeetCode-Go 题解:1684. Count the Number of Consistent Strings(一致字符串计数) LeetCode-Go 题解1684. Count the Number of Consistent Strings一致字符串计数【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go本篇技术指南以 LeetCode 第 1684 题Count the Number of Consistent Strings一致字符串为主题基于开源仓库 LeetCode-Go 中该题的 README.md 及其 Go 实现 展开。读者将掌握字符集合判定类问题的哈希表解法、题目约束下的复杂度分析与边界条件并了解该仓库的单元测试组织方式可直接复用到面试与日常刷题场景。题目描述与理解英文原题给定一个由互不相同的字符组成的字符串allowed以及一个字符串数组words。如果一个字符串中的所有字符都出现在allowed中则该字符串是consistent一致字符串。返回数组words中一致字符串的数目。You are given a string allowed consisting of distinct characters and an array of strings words. A string is consistent if all characters in the string appear in the string allowed. Return the number of consistent strings in the array words.题目大意中文给你一个由不同字符组成的字符串allowed和一个字符串数组words。如果一个字符串的每一个字符都在allowed中就称这个字符串是一致字符串。请你返回words数组中一致字符串的数目。关键语义点allowed中的字符互不相同distinct因此无需处理重复字符判定对象是words中每一个字符串的全部字符只要有一个字符不在allowed中该字符串即不满足条件字符集仅包含小写英文字母判定空间固定为 26 个字母allowed可为任意非空字符串长度 1 至 26words[i]长度最大为 10。示例剖析示例 1Input: allowed ab, words [ad,bd,aaab,baa,badab] Output: 2 Explanation: Strings aaab and baa are consistent since they only contain characters a and b.aaab仅含a、b一致 ✅baa仅含a、b一致 ✅ad含d不一致 ❌bd含d不一致 ❌badab含d不一致 ❌结果为 2。示例 2Input: allowed abc, words [a,b,c,ab,ac,bc,abc] Output: 7 Explanation: All strings are consistent.words中每个字符串的全部字符均落在{a, b, c}内7 个字符串全部一致。示例 3Input: allowed cad, words [cc,acd,b,ba,bac,bad,ac,d] Output: 4 Explanation: Strings cc, acd, ac, and d are consistent.cc含c一致 ✅acd含a,c,d一致 ✅ac含a,c一致 ✅d含d一致 ✅b、ba、bac、bad均含b不一致 ❌结果为 4。数据范围与约束约束取值words.length1 words.length 10^4allowed.length1 allowed.length 26words[i].length1 words[i].length 10allowed字符互不相同distinct字符范围仅含小写英文字母a-z这些约束决定了字符种类最多 26 个哈希表容量极小几乎不存在哈希冲突性能问题单词最长 10 个字符words最多 10^4 个单词单次完整遍历即可在极短时间内完成。解题思路这是典型的哈希表 集合成员判定问题整体思路非常直接将allowed中的每个字符存入哈希表map作为允许字符集合遍历words数组中的每个单词逐个检查其每个字符是否都能在集合中命中若某个单词的全部字符均命中则累加结果计数res若遇到任意一个不在集合中的字符立即标记该单词不合法并跳出内层循环提前终止避免无效遍历最终返回res。判断一个字符串是否一致本质是把字符串视作一个字符多重集合multiset检验其是否是该字符集合的子集。由于allowed中字符互不相同映射的 key 天然唯一map[rune]int中的 value 恒为 1因此该 map 只承担set集合的语义。仓库源码实现解析仓库中该题的完整实现位于 1684. Count the Number of Consistent Strings.go代码如下package leetcode func countConsistentStrings(allowed string, words []string) int { allowedMap, res, flag : map[rune]int{}, 0, true for _, str : range allowed { allowedMap[str] } for i : 0; i len(words); i { flag true for j : 0; j len(words[i]); j { if _, ok : allowedMap[rune(words[i][j])]; !ok { flag false break } } if flag { res } } return res }逐段剖析构建字符集合allowedMap, res, flag : map[rune]int{}, 0, true for _, str : range allowed { allowedMap[str] }使用map[rune]int存储允许字符。用rune作为 key是因为range遍历字符串时会按Unicode 码点rune迭代天然适配字符语义由于题目保证allowed字符互不相同allowedMap[str]实际等价于allowedMap[str] 1即只关心key 是否存在这是典型的 set 用法res为最终计数flag标记当前单词是否一致初始置true。遍历单词并判定for i : 0; i len(words); i { flag true for j : 0; j len(words[i]); j { if _, ok : allowedMap[rune(words[i][j])]; !ok { flag false break } } if flag { res } }外层循环遍历每个单词内层循环遍历单词的每个字节这里用下标words[i][j]取出的是byte类型因此需显式转换为rune再查表小写英文字母 ASCII 均小于 128byte 与 rune 数值一致转换安全使用 Go 的comma ok 惯用法_, ok : allowedMap[...]ok false表示字符不在集合中此时置flag false并break提前结束该单词的检查内层循环完整走完且flag仍为true说明该单词所有字符均合法res。复杂度分析时间复杂度O(N × M)其中 N 为words.length最大 10^4M 为单词平均长度最大 10。构建集合 O(|allowed|)判定阶段在最坏情况下遍历全部单词的全部字符空间复杂度O(|allowed|)即 O(26)哈希表仅存储allowed中的字符与words规模无关可视为常数级空间。单元测试与运行验证仓库为每道题配套了同名的_test.go测试文件本题目测试位于 1684. Count the Number of Consistent Strings_test.go。测试文件采用本仓库统一的表驱动测试table-driven test结构type question1684 struct { para1684 ans1684 } // para 是参数 // one 代表第一个参数 type para1684 struct { allowed string words []string } // ans 是答案 // one 代表第一个答案 type ans1684 struct { one int } func Test_Problem1684(t *testing.T) { qs : []question1684{ { para1684{ab, []string{ad, bd, aaab, baa, badab}}, ans1684{2}, }, { para1684{abc, []string{a, b, c, ab, ac, bc, abc}}, ans1684{7}, }, { para1684{cad, []string{cc, acd, b, ba, bac, bad, ac, d}}, ans1684{4}, }, } ... }测试用例与题目给出的三个示例一一对应分别覆盖部分一致允许集abwords中混有含d的不一致字符串期望输出 2全部一致允许集abcwords中所有字符串均只含a/b/c期望输出 7多种混合允许集cad同时验证单个重复字符cc、多字符组合acd、单字符d均判定为一致含b的字符串判定为不一致期望输出 4。运行测试在本仓库根目录下运行测试go test -v ./leetcode/1684.Count-the-Number-of-Consistent-Strings/若需验证该题的覆盖率可参考仓库根目录的 gotest.sh 中使用的覆盖测试方式对整个leetcode包执行go test -covermodeatomic -coverprofilecoverage.txt ./leetcode/...本仓库的go.mod声明模块为github.com/halfrost/LeetCode-GoGo 版本要求为go 1.19且通过replace指令本地关联了structures、template、ctl等子模块运行前请确认本地 Go 环境满足版本要求。进阶讨论与扩展优化点 1位掩码bitmask替代哈希表由于字符集固定为 26 个小写字母可以用一个int的低 26 位作为布尔掩码替代 map构建掩码对allowed中每个字符c执行mask | 1 (c - a)单词判定对单词中每个字符计算1 (c - a)并与mask做按位与结果非零即表示该字符在允许集合中。位运算方案将查询从哈希查找降为单次按位与常数更小空间占用仅一个int在words.length高达 10^4、单词最长 10 字符的约束下性能边际收益明显。注意哈希表方案的 O(N × M) 复杂度已经能够通过该题的全部数据位掩码属于常数级优化。优化点 2频率计数向量若题目变为统计每个字符出现次数均不超过允许次数例如allowed中允许重复字符则可将 map 升级为频率计数表先统计allowed中各字符次数再统计单词中各字符次数并逐一比较。当前题目因allowed字符互不相同且只做存在性判定频率语义不必要但该思路可平滑迁移到类似构成字符串类题目如判断能否用给定字符拼出目标单词。相关题型延伸一致字符串判定是字符串与集合类问题的入门题与之相关的常见扩展包括子集判定判断一个字符串的所有字符是否属于另一集合如 LeetCode 1160 找可由字符拼出的单词字符频率比较判断两个字符串是否互为字母异位词anagram位掩码集合运算用位向量表示字符集合以加速多重判定如单词搜索类题目的预处理。小结维度结论核心思路哈希表set存允许字符逐单词逐字符判定关键惯用法map[rune]int comma-ok 查询 提前break剪枝时间复杂度O(N × M)N ≤ 10^4M ≤ 10空间复杂度O(26)常数级仓库验证表驱动测试覆盖题目全部示例go test -v可直接运行通过本题可以掌握一套可复用的字符集合成员判定模板先建集合再逐元素查询遇非法立即终止。该模板适用于大量字符串过滤、集合子集校验类题目是面试中字符串与哈希表专题的基础功。参考文件索引题目文档Go 实现源码单元测试仓库覆盖测试脚本模块依赖与 Go 版本声明【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表