125. 验证回文串(简单)
题目
给定一个字符串 s。先把它“清洗”一遍:所有大写字母换成小写,所有既不是字母、也不是数字的字符删掉。如果清洗后的串正着读和反着读完全一样,就返回 true;否则返回 false。
这里的“字母数字”包括 a~z、A~Z 和 0~9;标点、空格、符号都要在比较时忽略。
自造示例:s = "No lemon, no melon!" → 清洗后是 "nolemonnomelon",正反读一样,返回 true。
再看:s = "Hello, World!" → 清洗后是 "helloworld",反转后是 "dlrowolleh",返回 false。
再看:s = " @# " → 清洗后是空串 "",空串正反读相同,返回 true。
约束:长度 1 ≤ s.length ≤ 2 × 105;s 仅由可打印 ASCII 字符组成。
思路
一句话:左右两个指针从两端向中间靠,跳过非法字符后比较两个“有效字符”的小写形式。
最直白的做法:先遍历一遍,把字母数字挑出来并转小写,拼成一个新串 clean;再比较 clean 和它的反转串。这个思路完全正确,时间 O(n),但要额外开一个 O(n) 的新串,而且要完整扫两遍。
关键观察:回文的核心是对称——第 i 个有效字符必须和第 倒数第 i 个有效字符相同。我们其实不需要把清洗后的串真的拼出来:从左右两端同时走,遇到标点、空格就跳过,遇到有效字符就转小写比较,一步到位。
于是选定相向双指针:左指针负责原串的开头,右指针负责原串的结尾;每次都先让两侧跳到最近的字母数字上,再比较。这样既不额外分配空间,又把“过滤”和“比较”合并成一次扫描。
解法
设 left = 0、right = s.length - 1,循环执行:
left向右移动,直到s[left]是字母或数字,或与right相遇。right向左移动,直到s[right]是字母或数字,或与left相遇。- 把两侧字符都转成小写比较;一旦不等,直接返回
false。 - 相等就让
left++、right--,继续检查下一对。 - 循环正常结束,说明所有对称位置都匹配,返回
true。
以 s
本篇为付费内容
您已阅读试读部分,购买后即可解锁全文。
⚠️ 本站内容已做唯一性标记并受版权保护,未经授权禁止转载,侵权必究。
还没有评论,来说两句?