ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LeetCode 953 Verifying an Alien Dictionary:用哈希表完成外星语字典序验证的 Go 解法

LeetCode 953 Verifying an Alien Dictionary:用哈希表完成外星语字典序验证的 Go 解法 LeetCode 953 Verifying an Alien Dictionary用哈希表完成外星语字典序验证的 Go 解法【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go导读本文基于 LeetCode-Go 仓库中 leetcode/0953.Verifying-an-Alien-Dictionary 的题目讲解结合 Go 源码实现 与其单元测试完整剖析 LeetCode 953 题「外星字典验证」的解法。读完本文你将掌握如何把「自定义字母顺序」映射为可比较的权值从而复用经典字典序比较逻辑并能独立写出具备边界处理能力前缀子串、单元素输入等的 Go 实现。题目背景与问题定义外星语同样使用 26 个英文小写字母但字母之间的相对顺序与地球上的英语不同。题目会给出一个字符串order它是 26 个小写字母的一个排列代表了该外星语的完整字母表顺序。给定一组用外星语书写的单词words以及该外星语的字母表顺序order只有当这些单词在外星语中按字典序lexicographical order排列时返回true否则返回false。其核心难点在于标准库的字符串比较基于 ASCII 顺序即英语字母序而本题需要把比较基准替换为order指定的自定义顺序因此必须先把order转成一张「字符 → 权值」的查找表再逐对单词进行手写比较。示例与约束条件原题文档给出了三个典型示例覆盖了判断为真、普通逆序和前缀子串三种情况示例 1words [hello,leetcode]order hlabcdefgijkmnopqrstuvwxyz输出true。因为在该外星语中h排在l之前所以hello小于leetcode序列有序。示例 2words [word,world,row]order worldabcefghijkmnpqstuvxyz输出false。因为该外星语中l排在d之前words[0]大于words[1]序列无序。示例 3words [apple,app]order abcdefghijklmnopqrstuvwxyz输出false。前三个字符app完全相同而第二个字符串更短。按字典序规则apple大于app因为l大于空字符∅——约定空字符小于任意其他字符。题目约束原文档 Note 部分1 words.length 100即单词数量至少为 11 words[i].length 20每个单词非空order.length 26字母表恰好覆盖全部小写字母且不重复words[i]与order中的所有字符均为英文小写字母。这意味着不需要考虑非法输入order一定包含全部 26 个字母比较时按字符直接查表即可无需做空指针或越界防御。解题思路原文档给出的解题思路是把 26 个字母的顺序先存入 map然后依次遍历判断字符串数组中字符串的大小。这是本题的标准做法整体分两步建表遍历order字符串把每个字符映射到它在order中的下标。下标越小说明该字母在外星字母表中越靠前、权值越小。由于约束保证order.length 26且字符互不重复映射是完备的一一对应。逐对比较对words中相邻的每一对单词按外星字母表权值从左到右逐字符比较决定这一对是否有序只有所有相邻对都有序整个序列才有序。字典序比较的完整规则需要同时处理两种情况字符相异找到第一个权值不同的位置权值小者所在的单词更小。例如示例 2 中word与world的前三个字符相同第 4 位d的权值大于l因此word world立即判定无序。前缀相等若较短单词恰好是较长单词的前缀则较短者更小因为约定「空字符」小于任何其他字符。例如示例 3 中apple与app比较完app的全部字符仍未分出胜负此时apple还有剩余字符故apple app判定无序。反过来[app, apple]则是有序的。Go 源码实现与逐行解析仓库中的解法位于 953. Verifying an Alien Dictionary.go完整代码如下package leetcode func isAlienSorted(words []string, order string) bool { if len(words) 2 { return true } hash : make(map[byte]int) for i : 0; i len(order); i { hash[order[i]] i } for i : 0; i len(words)-1; i { pointer, word, wordplus : 0, words[i], words[i1] for pointer len(word) pointer len(wordplus) { if hash[word[pointer]] hash[wordplus[pointer]] { return false } if hash[word[pointer]] hash[wordplus[pointer]] { break } else { pointer pointer 1 } } if pointer len(word) pointer len(wordplus) { return false } } return true }下面逐段说明其关键逻辑前置剪枝第 4-6 行len(words) 2时直接返回true。只有一个单词或没有单词时不存在相邻对需要比较序列恒有序。这同时也是对题目约束1 words.length的稳健处理。建立权值表第 7-10 行hash的类型是map[byte]inthash[order[i]] i把每个字符映射到其在order中的下标。此后任意两个字符的比较都被归约为两个整数的比较这正是把「自定义顺序」转换成「可比权值」的关键一步。从代码结构看这里也可用长度为 26 的数组替代 map 以获得更紧凑的内存但 map 的写法更直观、语义更清晰。相邻单词对比较第 11-12 行外层循环遍历words[i]与words[i1]相邻对pointer是当前比较到的字符下标word与wordplus分别指向前后两个单词。逐字符扫描第 13-22 行内层循环在pointer同时小于两个单词长度时执行若hash[word[pointer]] hash[wordplus[pointer]]说明当前位置外星字母权值前者大于后者这一对单词逆序立即返回false若权值前者小于后者说明当前这对单词已经分出先后break跳出内层循环继续检查下一对若权值相等pointer自增继续比较下一位。前缀处理第 23-25 行内层循环退出后如果pointer仍然小于word的长度、同时已经不小于wordplus的长度说明wordplus是word的前缀且更短——例如apple与app——按字典序规则word应大于wordplus因此返回false。这正好复现了题目示例 3 中「空字符小于任意字符」的约定。复杂度分析时间复杂度建表阶段遍历order耗时 O(26) 即常数比较阶段对任意相邻单词对最坏情况是比较完两个单词的全部字符单词最大长度为 20共words.length - 1对因此整体为 O(N × L)其中 N 为单词个数不超过 100、L 为单词最大长度不超过 20。在本仓库实现中绝大多数情况下内层循环会在权值首次不同的位置提前break实际运行更快。空间复杂度hash表最多存储 26 个键值对属于 O(26) 的常数空间不随输入规模增长。由于题目规模极小最多 100 个单词、每个最多 20 个字符该解法在时间和空间上都远优于题目限制这也是原文档将其归为「简单题」的原因之一。单元测试与结果验证仓库为该实现配套了完整的单元测试见 953. Verifying an Alien Dictionary_test.go。测试采用本仓库统一的「参数-答案」结构question953聚合输入para953one为单词数组、two为字母顺序与期望输出ans953布尔值共覆盖四个用例输入 words输入 order期望输出验证点[hello,leetcode]hlabcdefgijkmnopqrstuvwxyztrue正常有序对应题目示例 1[word,world,row]worldabcefghijkmnpqstuvxyzfalse相邻对逆序对应题目示例 2[apple,app]abcdefghijklmnopqrstuvwxyzfalse前缀子串逆序对应题目示例 3[apple]abcdefghijklmnopqrstuvwxyztrue单元素边界len(words) 2直接返回true其中第四个用例是仓库额外补充的边界测试只有一个单词时没有可比较的相邻对函数应在建表后、进入外层循环前就返回true它直接覆盖了源码第 4-6 行的前置剪枝分支。测试通过fmt.Printf打印每个用例的输入与输出便于在go test -v下人工核对结果。边界情况与易错点总结结合源码实现解答本题时最容易出错的是以下三点前缀相等的处理不能漏[apple, app]这类用例中内层循环因pointer到达较短单词末尾而自然退出此时若不检查剩余长度会误判为有序。仓库实现用pointer len(word) pointer len(wordplus)显式拦截了这种情况。比较方向必须与题目一致题目要求返回words是否按升序排列因此只有发现words[i] words[i1]时才应返回false相等字符应继续向后比较而非立即返回。建表必须基于order而非英文字母序直接使用 Go 字符串的、运算符比较会得到错误答案因为那是 ASCII 顺序。本题的核心就是把order翻译为权值表后再比较。小结LeetCode 953「Verifying an Alien Dictionary」是哈希表与字符串比较相结合的入门级题目先用map将自定义外星字母顺序固化为字符权值再逐对执行标准字典序比较并妥善处理前缀子串与单元素边界。LeetCode-Go 仓库中的实现代码简洁、测试覆盖完整含三个官方示例与一个边界用例可作为同类「自定义排序规则」题目例如按给定顺序排序字符串的直接参考模板。如需完整题目描述与中文题解可回看仓库中的 README.md。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表