news 2026/6/10 20:29:19

力扣125.验证回文串-双指针

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
力扣125.验证回文串-双指针

问题描述

在编程面试中,验证回文串是一个经典问题。题目要求我们判断一个字符串是否为回文串,但有两个特殊要求:

  1. 只考虑字母和数字字符

  2. 忽略字符的大小写

示例 1:

text

输入: "A man, a plan, a canal: Panama" 输出: true 解释: "amanaplanacanalpanama" 是回文串

示例 2:

text

输入: "race a car" 输出: false 解释: "raceacar" 不是回文串

什么是回文串?

回文串是指正着读和反着读都一样的字符串。例如:

  • "level"

  • "radar"

  • "上海自来水来自海上"

解决:双指针法

核心思想

使用两个指针从字符串的两端向中间移动,逐步比较字符是否相同。

算法步骤

  1. 初始化指针

    • 左指针i指向字符串开头

    • 右指针j指向字符串结尾

  2. 主循环

    • 当左指针小于右指针时继续比较

  3. 跳过非字母数字字符

    • 如果左指针指向的字符不是字母或数字,左指针右移

    • 如果右指针指向的字符不是字母或数字,右指针左移

  4. 比较字符

    • 将字符转换为小写后比较

    • 如果相同,两个指针都向中间移动

    • 如果不同,直接返回false

  5. 结束条件

    • 当所有有效字符都比较完毕且都相同时,返回true

代码实现

class Solution { public boolean isPalindrome(String s) { int i = 0; // 左指针 int j = s.length() - 1; // 右指针 while (i < j) { // 主循环 // 跳过左侧非字母数字字符 if (!Character.isLetterOrDigit(s.charAt(i))) { i++; } // 跳过右侧非字母数字字符 else if (!Character.isLetterOrDigit(s.charAt(j))) { j--; } // 比较字符(忽略大小写) else if (Character.toLowerCase(s.charAt(i)) == Character.toLowerCase(s.charAt(j))) { i++; // 左指针右移 j--; // 右指针左移 } // 字符不同,不是回文串 else { return false; } } return true; // 所有字符匹配 } }

算法详解

关键方法解析

1.Character.isLetterOrDigit(char ch)

这个方法用于判断字符是否为字母或数字:

  • 字母:A-Z, a-z

  • 数字:0-9

  • 其他字符(标点、空格等)返回false

2.Character.toLowerCase(char ch)

将字符转换为小写:

  • 大写字母:A → a

  • 小写字母和数字:保持不变

  • 确保大小写不敏感的比较

复杂度分析

时间复杂度:O(n)

  • n是字符串的长度

  • 每个字符最多被访问一次(左指针或右指针)

  • 最坏情况下需要遍历整个字符串

空间复杂度:O(1)

  • 只使用了常数级别的额外空间

  • 只存储了两个指针和几个临时变量

优化技巧

1. 预处理字符串(备选方案)

可以先清洗字符串,再判断:

public boolean isPalindromeAlternative(String s) { // 1. 转换为小写 // 2. 移除非字母数字字符 String cleaned = s.toLowerCase().replaceAll("[^a-z0-9]", ""); // 3. 判断清洗后的字符串是否为回文 int left = 0, right = cleaned.length() - 1; while (left < right) { if (cleaned.charAt(left) != cleaned.charAt(right)) { return false; } left++; right--; } return true; }

优缺点:

  • 优点:代码更简洁

  • 缺点:需要额外的O(n)空间存储清洗后的字符串

2. 使用StringBuilder反转

public boolean isPalindromeWithBuilder(String s) { String cleaned = s.toLowerCase().replaceAll("[^a-z0-9]", ""); String reversed = new StringBuilder(cleaned).reverse().toString(); return cleaned.equals(reversed); }

优缺点:

  • 优点:代码极简

  • 缺点:需要额外空间,且比较整个字符串

常见错误

错误1:忘记处理大小写

java

// 错误代码 if (s.charAt(i) == s.charAt(j)) { ... } // 应使用toLowerCase转换

错误2:指针移动逻辑错误

java

// 错误代码:同时移动指针 if (!Character.isLetterOrDigit(s.charAt(i))) { i++; j--; // 错误:不应该同时移动j }

错误3:边界条件处理不当

java

// 错误:没有考虑空字符串或全无效字符的情况 if (s.length() == 0) return false; // 应返回true

扩展思考

1. 如何修改代码以支持Unicode字符?

使用Character.isLetter()Character.isDigit()分开判断:

java

if (!Character.isLetter(c) && !Character.isDigit(c)) { // 跳过 }

2. 如何找到最长回文子串?

这是LeetCode第5题,可以使用动态规划中心扩展法解决。

3. 如何统计字符串中的回文子串数量?

可以使用中心扩展法,统计以每个字符为中心的回文数量。

总结

验证回文串问题虽然简单,但涵盖了多个重要编程概念:

  • 双指针技巧:高效的遍历方法

  • 字符处理:大小写转换、字符类型判断

  • 边界条件:空字符串、特殊字符处理

  • 时间复杂度优化:O(n)时间复杂度和O(1)空间复杂度

掌握这个问题的解法不仅有助于通过面试,还能加深对字符串处理和算法优化的理解。

关键要点记忆:

  1. 使用双指针从两端向中间遍历

  2. 使用Character.isLetterOrDigit()过滤无效字符

  3. 使用Character.toLowerCase()统一大小写

  4. 注意边界条件的处理

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 11:50:41

Windows 系统 Qt 下载、安装与环境配置全教程

前言 Qt 是一款跨平台的 C 图形用户界面应用程序开发框架&#xff0c;凭借丰富的控件库、便捷的跨平台特性和强大的 Qt Creator 集成开发环境&#xff0c;成为桌面端、嵌入式端开发的主流选择。本文将从Qt 版本选择、官网下载、分步安装、环境变量配置、编译工具验证到第一个 …

作者头像 李华
网站建设 2026/6/10 12:00:07

【Vue 功能总结】Element UI 级联组件实现

一、Element UI 级联组件概述 Element UI 的级联选择器(Cascader)是一个用于多级数据选择的强大组件,特别适合处理省市区选择、商品分类等层级关系明确的数据场景。它通过递归渲染的方式展示多级数据结构,并支持懒加载、自定义节点内容等高级特性。 二、基础实现与代码解析 …

作者头像 李华
网站建设 2026/6/10 11:58:49

【2025最新】基于SpringBoot+Vue的酒店管理系统管理系统源码+MyBatis+MySQL

摘要 随着旅游业的快速发展和信息化建设的不断深入&#xff0c;酒店行业对高效、智能的管理系统需求日益增长。传统酒店管理方式依赖人工操作&#xff0c;存在效率低、错误率高、数据管理混乱等问题&#xff0c;难以满足现代酒店业务的需求。基于此&#xff0c;开发一款功能完善…

作者头像 李华
网站建设 2026/6/10 11:59:23

罗德与施瓦茨ZV-Z229校准件

罗德与施瓦茨ZV-Z229校准件概述罗德与施瓦茨ZV-Z229是专为矢量网络分析仪&#xff08;VNA&#xff09;设计的校准件&#xff0c;用于实现高精度的S参数测量校准。该校准件通常属于机械校准套件&#xff08;如ZV-Z21x系列&#xff09;的一部分&#xff0c;支持SOLT&#xff08;短…

作者头像 李华
网站建设 2026/6/10 11:59:08

【无用之美】每个浪漫主义者的身边都要有一个现实主义的朋友,让他不要离这个世界太远。每个现实主义者身边都要有一个浪漫主义的朋友,让他还记得自己生而为人而非机器

上一篇&#xff1a;【读后感2 渡不过的约旦河&#xff0c;栖身的迦南岸】在迦南的那一边——&#xff08;爱尔兰&#xff09;巴斯蒂安‧巴里 目录 前言 开篇词 别忘了浪漫的生活 前言 这个专栏可能会显得格格不入。 整理技术笔记的同时也整理了一下自己的读书笔记&#…

作者头像 李华
网站建设 2026/6/10 19:13:54

Java异常处理

Java的异常处理机制是保障程序健壮性的核心。它通过面向对象的方式管理运行时错误&#xff0c;将异常封装为对象&#xff0c;并提供了完整的处理框架。下面这个表格总结了其核心组件和常见异常类型&#xff0c;帮助你快速把握全局。组件/类型类别关键点/子类主要用途try-catch-…

作者头像 李华