尧图精选

LeetCode-Go 题解精讲:125. Valid Palindrome 双指针判定有效回文串

🕒 发布时间:2026/9/11 18:17:49 📁 来源:尧图网络
LeetCode-Go 题解精讲125. Valid Palindrome 双指针判定有效回文串【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go导读本篇基于 LeetCode-Go 仓库中 125. Valid Palindrome 题解 展开深入讲解如何用 Go 在 O(n) 时间内判定一个字符串是否为有效回文串——即忽略大小写、跳过所有非字母数字字符后判断是否回文。读完本文你将掌握双指针扫描的完整套路、字符过滤的字节级实现细节、边界条件尤其空字符串的处理方式以及配套测试用例与覆盖率验证方法并能举一反三迁移到链表的回文判定问题。题目回顾什么是有效回文串原题描述见 README.mdGiven a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.给定一个字符串判断它是否是回文串只考虑字母和数字字符并且忽略大小写。官方给出的两个示例A man, a plan, a canal: Panama is a palindrome. race a car is not a palindrome.第一个例子中去掉空格、冒号、逗号等标点并统一小写后得到amanaplanacanalpanama正读反读完全一致因此是回文第二个例子去掉空格后得到raceacar反读为racacear不一致因此不是回文。面试中的经典一问空字符串题目在 Note 中特意提醒Have you consider that the string might be empty? This is a good question to ask during an interview.空字符串是面试中非常值得主动确认的边界情况。本题明确给出定义空字符串视为有效的回文串we define empty string as valid palindrome。这一约定也直接体现在仓库的源码实现中——当s为空时左右指针初始即越界循环体一次都不会进入函数直接返回true。解题思路简单题背后的双指针范式原文档的解题思路只有一句话简单题按照题意做即可。这确实是本题的定位但按照题意做有三个必须落实的环节大小写归一化先把整个字符串转为小写或大写消除大小写差异字符过滤只保留字母a-z和数字0-9跳过空格、标点等一切非字母数字字符回文判定用左右双指针从两端向中间收敛逐对比较。这三个环节在 125. Valid Palindrome.go 中均有对应的代码实现下面逐一拆解。源码剖析双指针 字节级字符过滤仓库中的完整解法如下125. Valid Palindrome.gopackage leetcode import ( strings ) func isPalindrome(s string) bool { s strings.ToLower(s) i, j : 0, len(s)-1 for i j { for i j !isChar(s[i]) { i } for i j !isChar(s[j]) { j-- } if s[i] ! s[j] { return false } i j-- } return true } // 判断 c 是否是字符或者数字 func isChar(c byte) bool { if (a c c z) || (0 c c 9) { return true } return false }第一步strings.ToLower统一大小写s strings.ToLower(s)一次遍历将整个字符串转为小写。转换后字符比较只需考虑小写字母a-z与数字0-9为后续isChar的区间判断扫清了障碍。这是把忽略大小写的题意翻译成代码的最直接方式。第二步双指针跳过非字母数字i, j : 0, len(s)-1 for i j { for i j !isChar(s[i]) { i } for i j !isChar(s[j]) { j-- } ... }外层循环以i j为终止条件内层两个循环分别让左指针i向右、右指针j向左跳过所有非字母数字字符。注意内层循环同样带着i j的条件防止指针越界——例如当字符串几乎全是标点时i可能一路递增到与j相遇甚至越过i j的守卫保证了数组下标访问s[i]、s[j]始终安全。第三步字符比较与指针收敛if s[i] ! s[j] { return false } i j--两端字符一旦不等立即返回false具备短路特性无需继续扫描相等则两端指针同时向中间收敛进入下一轮比较。循环正常结束说明所有对应位置都相等返回true。辅助函数isChar什么是字母数字// 判断 c 是否是字符或者数字 func isChar(c byte) bool { if (a c c z) || (0 c c 9) { return true } return false }由于字符串已在第一步统一转为小写这里只需判断小写字母区间[a,z]与数字区间[0,9]即可。数字字符在本题中同样属于alphanumeric characters是有效参与回文比较的字符例如测试用例0p中的0就必须参与比较。边界条件全梳理从源码实现可以推导出以下边界行为均可在面试中主动向面试官确认或直接说明输入处理过程结果空字符串len(s)-1 -1i j不成立循环不执行true题目明确定义单个字符0、ai j循环不执行true单字符天然回文仅含标点/空格 ,. 指针不断跳过最终i jtrue过滤后为空串A man, a plan, a canal: Panama过滤小写后为amanaplanacanalpanamatruerace a car过滤后为raceacar首尾rvsr相等继续比较avsa…到evsc不等false0p0与p均为字母数字且不等false关于 Unicode 的说明从源码结构看isChar基于byte进行区间判断只识别ASCII字母与数字。对于中文字符、带变音符号的拉丁字符等 Unicode 字符会被当作非字母数字字符直接跳过不参与比较。若题目要求支持全量 Unicode 字母数字如 Java 的Character.isLetterOrDigit语义需要对过滤逻辑做扩展就本题 LeetCode 的测试数据范围而言当前的 ASCII 字节判断已经足够。测试用例与验证仓库为本题配备了完整的表驱动测试125. Valid Palindrome_test.go覆盖了上述关键边界tcs : []struct { s string ans bool }{ {0p, false}, // 数字与字母直接比较不等 {0, true}, // 单字符 {race a car, false}, // 官方反例 {A man, a plan, a canal: Panama, true}, // 官方正例 }这组用例很有讲究0覆盖单字符天然回文与数字参与比较0p覆盖字母与数字直接比较的场景两个官方示例一正一反验证了跳过空格、标点、忽略大小写的完整链路。运行方式仓库使用标准的 Go 测试体系进入仓库根目录后执行# 运行本题全部测试用例 go test -v -run Test_Problem125 ./leetcode/0125.Valid-Palindrome/ # 运行整个 leetcode 包的全部测试 go test -v ./leetcode/...其中-run Test_Problem125按测试函数名精确匹配本题的Test_Problem125。测试通过fmt.Printf打印每个用例的输入与输出运行-v模式即可直观看到结果。覆盖率验证仓库根目录的 gotest.sh 脚本使用 Go 1.10 的多包单次覆盖采集方式生成合法且可被 Codecov 解析的覆盖率文件go test -covermodeatomic -coverprofilecoverage.txt ./leetcode/...-covermodeatomic用于支持并发的原子计数-coverprofilecoverage.txt将覆盖结果写入根目录下的coverage.txt该文件已存在于仓库中。本题的isPalindrome及其测试位于leetcode/0125.Valid-Palindrome/包内会随./leetcode/...一并纳入覆盖统计契合项目 README 中宣称的 100% test coverage 目标。复杂度分析时间复杂度O(n)其中 n 为字符串长度。strings.ToLower为一次 O(n) 遍历双指针扫描中每个字符最多被指针访问一次整体仍是 O(n)。内层跳过循环只是让指针不走回头路不会引入额外轮次。空间复杂度O(1)。除ToLower产生的新字符串外仅使用i、j两个整型变量不依赖输入规模。若希望做到严格 O(1) 额外空间可改为逐字节toLower后原地比较代价是代码稍显繁琐。思路迁移双指针范式在回文类问题中的延伸双指针从两端向中间收敛是回文类问题最核心的套路在本仓库中可以找到大量同源题目234. Palindrome Linked List数组双指针无法直接用于链表解法改为先找到中间结点再反转后半段链表最后逐结点比较是本题思路在链表数据结构上的经典变体要求 O(n) 时间、O(1) 空间0009. Palindrome Number判断整数回文可先转字符串套用本题思路也可纯数学方式反转后半部分数字0005. Longest-Palindromic-Substring从判断回文升级为寻找最长回文子串中心扩展法同样依赖双向比较0131. Palindrome Partitioning在回文判定基础上叠加回溯与动态规划是进阶版应用。由此可见125 题虽然只是简单题但它承载的双指针与字符过滤思想是后续一系列中等、困难题目的基石。吃透本题的边界处理空串、纯标点、数字参与比较再向链表、DP 方向迁移即可系统掌握回文主题。小结本文以 LeetCode-Go 仓库中 125. Valid Palindrome 的题解文档为骨架逐行解读了 isPalindrome 实现先用strings.ToLower归一化大小写再用isChar字节级过滤非字母数字最后以双指针向中间收敛完成判定并通过 测试文件 与 gotest.sh 验证了运行与覆盖率采集方式。整套解法时间 O(n)、空间 O(1)边界处理完备是回文系列题目的标准起手式。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →