当前位置: 首页 > news >正文

LeetCode 面试经典 150 题之验证回文串:双指针解题思路详解

在 LeetCode 面试经典 150 题中,“验证回文串” 是一道极具代表性的字符串处理题目。它不仅考察我们对字符串中有效字符(字母、数字)的筛选能力,还考验对 “回文” 这一对称特性的理解,而双指针法则是解决这类对称匹配问题的高效方案。掌握这道题的解题逻辑,能帮助我们在面对类似 “对称校验” 类题目时快速找到突破口,同时提升对边界条件的处理意识。

一、题目概览与链接

首先明确题目核心要求:给定字符串 s,判断它是否为回文串。这里的回文串需满足两个特殊规则:一是仅考虑字符串中的字母和数字字符,忽略空格、标点、符号等非有效字符;二是忽略字母的大小写差异(例如 'P' 和 'p' 视为相同字符)。若满足上述条件且正读、反读一致,则返回 true,否则返回 false。

题目链接:LeetCode 125. 验证LeetCode 125.验证回文串(点击链接可直接跳转至题目页面,建议先查看题目中的示例,如 "A man, a plan, a canal: Panama" 是回文串、"race a car" 不是回文串,提前熟悉规则细节)

二、双指针解题思路深度拆解

双指针思路是验证回文串的最优解法之一,核心是 “从字符串两端向中间靠拢,动态筛选有效字符并对比对称性”。

1. 核心逻辑:双指针的 “对称校验” 原理

回文串的本质是 “对称”—— 从左到右读和从右到左读的有效字符序列完全一致。基于这一特性,我们设置两个指针:

  • 左指针 left:从字符串的起始位置(索引 0)开始,向右移动;
  • 右指针 right:从字符串的末尾位置(索引 s.length() - 1)开始,向左移动。

通过两个指针向中间靠拢,每一轮循环完成 “筛选有效字符→对比对称字符→移动指针” 的流程,直到 left >= right(此时所有对称位置的有效字符已对比完毕)。这种思路无需额外存储字符串,仅通过指针移动和字符判断即可完成验证,效率高且空间消耗低。

2. 循环步骤详解

步骤 1:筛选左指针的有效字符(跳过非字母 / 数字)

“如果 s[left] 不是字母或数字,指针 left 右移,直到 s[left] 是字母或数字”

  • 核心目的:排除非有效字符对回文判断的干扰。例如字符串 "A man, a plan" 中,左指针初始指向 'A'(有效字符),无需移动;若左指针指向 ',' 或空格(非有效字符),则需持续右移,直到找到下一个字母或数字。
  • 关键注意点:必须在循环中加入 left < right 的判断。若字符串全是非有效字符,左指针持续右移可能超过右指针,导致索引越界。加入 left < right 可确保指针移动在安全范围内,避免程序报错。
步骤 2:筛选右指针的有效字符(跳过非字母 / 数字)

“如果 s[right] 不是字母或数字,指针 right 左移,直到 s[right] 是字母或数字”

  • 逻辑与步骤 1 对称:右指针从字符串末尾开始,向左跳过非有效字符,最终指向当前最右侧的有效字符。例如字符串 "canal: Panama",右指针初始指向 'a'(Panama 的最后一个字母,有效字符),无需移动;若右指针指向 ':' 或空格,则持续左移,直到找到有效字符。
  • 示例场景:对于字符串 " hello world! "(首尾均有空格),左指针需跳过开头的空格,最终指向 'h';右指针需跳过末尾的 '!' 和空格,最终指向 'd',确保后续对比的是真正的有效字符。
步骤 3:对比对称字符,移动指针

“如果 s[left] 和 s[right] 的小写形式不相等,返回 false;指针 left 右移一位,指针 right 左移一位,继续下一次循环”

  • 大小写统一:题目要求忽略字母大小写,因此需将两个指针指向的有效字符转为同一大小写(这里选择小写,转为大写也可)。例如 'M' 转为小写是 'm','p' 转为小写仍是 'p',确保 'M' 和 'm' 能被判定为相等。
  • 早停逻辑:一旦发现某一对对称字符不相等,立即返回 false,无需继续对比后续字符,提升算法效率。例如字符串 "race a car",当左指针指向 'e'、右指针指向 'a' 时,两者小写形式不相等,直接返回 false,避免多余的循环操作。
  • 指针移动:若字符对比相等,左指针右移、右指针左移,向中间靠拢,进入下一轮循环,继续验证下一对对称字符。

3. 循环终止条件与结果判定

“循环以下过程,直至 left >= right;循环结束,返回 true”

  • 终止条件的意义:当 left == right 时,说明指针指向字符串的中间位置(单个字符),单个字符本身具有对称性,无需对比;当 left > right 时,说明所有对称位置的有效字符都已对比完毕,且全部相等,此时循环终止。
  • 返回 true 的合理性:循环能正常结束,意味着没有任何一对对称字符不相等,且所有非有效字符都已被跳过,满足回文串的定义,因此返回 true。

4. 典型示例演示

为了更直观地掌握双指针的运行过程,我们以两道典型题目示例为例,完整演示解题步骤:

示例 1:有效回文串(含特殊字符)

s = "A man, a plan, a canal: Panama"(长度为 30)

  1. 初始化指针:left = 0(指向 'A'),right = 29(指向 'a')。
  1. 第一轮循环
    • 步骤 1:'A' 是字母(有效),left 不移动;
    • 步骤 2:'a' 是字母(有效),right 不移动;
    • 步骤 3:'A' 小写为 'a','a' 小写为 'a',相等;left = 1,right = 28。
  1. 后续循环
    • left = 1 指向空格(非有效),右移至 2('m');right = 28 指向空格(非有效),左移至 27('m');
    • 对比 'm' 和 'm'(相等),指针继续移动;
    • 持续重复步骤,直到 left >= right,循环终止,返回 true。
示例 2:非回文串(中间字符不匹配)

s = "race a car"(长度为 7)

  1. 初始化指针:left = 0(指向 'r'),right = 6(指向 'r')。
  1. 前几轮循环
    • 对比 'r' 和 'r'(相等),left = 1,right = 5;
    • 对比 'a' 和 'a'(相等),left = 2,right = 4;
    • 对比 'c' 和 'c'(相等),left = 3,right = 3(此时 left == right,本应终止,但需继续处理非有效字符)。
  1. 关键轮次
    • left = 3 指向 'e'(有效),right = 3 指向 'e'(有效),对比相等;left = 4,right = 2(此时 left > right,但实际因中间有空格,需重新筛选);
    • 修正:left = 3 指向 'e',right = 4 指向空格(非有效),左移至 3(指向 'a');
    • 对比 'e'(小写 'e')和 'a'(小写 'a'),不相等,返回 false。

三、复杂度分析

1. 时间复杂度:O (n)

  • 其中 n 是字符串 s 的长度。
  • 双指针 left 和 right 总共遍历字符串一次:左指针从起始位置到中间,右指针从末尾位置到中间,每个字符最多被访问一次(筛选非有效字符时,每个字符仅被判断一次,不会重复处理)。每一轮循环中的字符判断、大小写转换、指针移动均为常数时间操作(O (1)),因此总时间复杂度为 O (n),是最优的时间复杂度。

2. 空间复杂度:O (1)

  • 整个算法仅使用了 left 和 right 两个指针变量,未使用任何额外的数组、字符串或其他数据结构,空间占用不随字符串长度的变化而变化,始终保持常数级别。因此空间复杂度为 O (1),属于 “原地算法”,内存使用效率极高。

四、代码实现

根据上述双指针思路,我们提供 Java、Python两种主流编程语言的完整代码:

1. Java 代码

class Solution {public boolean isPalindrome(String s) {int left = 0,right = s.length()-1;while (left < right){while (left < right && !Character.isLetterOrDigit(s.charAt(left))){left++;}while (left < right && !Character.isLetterOrDigit(s.charAt(right))){right--;}if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))){return false;}left++;right--;}return true;}
}

2. Python 代码

class Solution:def isPalindrome(self, s: str) -> bool:left,right = 0,len(s) - 1while left < right:while left < right and not s[left].isalnum():left += 1while left < right and not s[right].isalnum():right -= 1if s[left].lower() != s[right].lower():return Falseleft += 1right -= 1return True

五、总结与拓展

“验证回文串” 这道题的核心是利用双指针的 “对称特性”,动态筛选有效字符并对比,既保证了效率,又降低了空间消耗。通过这道题,我们可以提炼出解决 “对称匹配” 类问题的通用思路:

  1. 确定对称的起点(通常是两端或中心);
  1. 筛选有效元素,排除干扰项;
  1. 对比对称位置的元素,发现不匹配立即终止;
  1. 移动指针 / 索引,直至遍历完所有对称位置。

这道题虽然难度中等,但能很好地锻炼我们的 “问题拆解能力” 和 “边界处理意识”。希望通过本文的分析,你能彻底掌握双指针法在验证回文串中的应用,并且能将该思想运用到其他题目中。

http://www.dtcms.com/a/391625.html

相关文章:

  • pandas在AI中与其他库的协作
  • 【软件测试】第5章 测试分类(下)
  • 二物理层-真题-
  • c康复训练 01
  • MLP和CNN在图片识别中的对比——基于猫狗分类项目的实战分析
  • Node-Choice
  • PyQt6之滚动条
  • 使用OpenVINO将PP-OCRv5模型部署在Intel显卡上
  • 【图像处理基石】图像复原方面有哪些经典算法?
  • setTimeout定时器不生效- useRef 的特点/作用
  • 钻井的 “导航仪”:一文读懂单点、多点与随钻测量
  • CKS-CN 考试知识点分享(8) ingress 公开 https 服务
  • ​​[硬件电路-259]:LM4040AIM3 精密电压基准源: 管脚定义、概述、功能、技术指标、使用场景、原理
  • C语言:实现阶乘和计算
  • 鸿蒙应用开发——AppStorageV2和PersistenceV2的使用
  • shell脚本实现docker镜像批量保存并上传至Harbor仓库
  • 用 EzCaptcha 优化 reCAPTCHA 低通过率问题
  • 在docker中构建Vue项目
  • 力扣1895. 最大的幻方
  • Linux入门(四)
  • 以下是与LoRa技术相关的数学公式整理
  • (3) rust和前端交互
  • TextFlux重磅发布:告别复杂控制信号!多语种高保真场景文本编辑新时代
  • A股大盘数据-20250919分析
  • [x-cmd] X-CMD 的依赖非常精简,即装即用,无需额外配置
  • TM52F1363 电子元器件 海速芯 8位高性能微控制器(MCU)技术解析
  • 打工人日报#20250919
  • vue3学习日记(十九):组件实例详解
  • 【开题答辩全过程】以 基于python的订餐系统为例,包含答辩的问题和答案
  • 题解:CF2143E Make Good