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

三种解法(数组、栈、快慢指针)全面解析——力扣234.回文链表全解析

力扣234.回文链表全解析

在这里插入图片描述


一、题目描述

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表
如果是,返回 true;否则,返回 false


示例 1:

输入:head = [1,2,2,1]
输出:true

示例 2:

输入:head = [1,2]
输出:false

提示:

  • 链表中节点数目在范围 [1, 10⁵]
  • 0 <= Node.val <= 9

进阶要求:

你能否只用 O(n) 时间复杂度 和 O(1) 空间复杂度解决此题?


二、思路总览

判断链表是否为回文,本质是要看:

链表从左往右与从右往左读是否相同。

我们可以分三种方法逐步优化:

方法思路时间复杂度空间复杂度
方法一转成数组后双指针比较O(n)O(n)
方法二栈辅助比较O(n)O(n)
方法三快慢指针 + 反转链表O(n)O(1)

下面我们逐一讲解。


三、方法一:转为数组法(思路直观)

思路

  1. 遍历链表,把所有节点值存入数组;
  2. 用双指针从头尾同时向中间比较;
  3. 若发现不相等,返回 false;否则返回 true

代码实现

class Solution {public boolean isPalindrome(ListNode head) {List<Integer> list = new ArrayList<>();ListNode curr = head;while (curr != null) {list.add(curr.val);curr = curr.next;}int left = 0, right = list.size() - 1;while (left < right) {if (!list.get(left).equals(list.get(right))) {return false;}left++;right--;}return true;}
}

在这里插入图片描述


复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

四、方法二:栈法(利用后进先出特性)

思路

  1. 遍历链表,将所有节点压入栈;
  2. 再次遍历链表,每次弹出一个元素进行比较;
  3. 若有不一致则返回 false

代码实现

class Solution {public boolean isPalindrome(ListNode head) {Stack<Integer> stack = new Stack<>();ListNode curr = head;while (curr != null) {stack.push(curr.val);curr = curr.next;}curr = head;while (curr != null) {if (curr.val != stack.pop()) {return false;}curr = curr.next;}return true;}
}

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

五、方法三:快慢指针 + 链表反转(最优解)

核心思想

利用“反转链表”的技巧来节省空间:

  1. 使用快慢指针 fastslow

    • fast 一次走两步,slow 一次走一步;
    • fast 到达末尾时,slow 到达中点。
  2. 反转后半部分链表。

  3. 从头和中点开始同时遍历,比较对应节点值是否相等。

  4. 可选:比较完成后再把链表恢复原状(面试时可选)。


图解思路

以链表 [1, 2, 2, 1] 为例:

  1. 找到中点:slow 停在第二个 2

  2. 反转右半部分:[2, 1] → [1, 2]

  3. 比较前后两半:

    1 == 1
    2 == 2
    
  4. 全部相等 → 回文。


class Solution {public boolean isPalindrome(ListNode head) {if (head == null || head.next == null) return true;// 1. 快慢指针找中点ListNode slow = head, fast = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}// 2. 反转后半部分ListNode secondHalf = reverseList(slow);// 3. 比较两半ListNode p1 = head, p2 = secondHalf;boolean isPalin = true;while (p2 != null) {if (p1.val != p2.val) {isPalin = false;break;}p1 = p1.next;p2 = p2.next;}// 4. 可选:恢复链表结构// reverseList(secondHalf);return isPalin;}private ListNode reverseList(ListNode head) {ListNode prev = null, curr = head;while (curr != null) {ListNode next = curr.next;curr.next = prev;prev = curr;curr = next;}return prev;}
}

复杂度分析

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

六、总结对比

方法时间复杂度空间复杂度优点缺点
数组法O(n)O(n)简单易懂占空间
栈法O(n)O(n)直观好理解同样占空间
快慢指针O(n)O(1)最优、工程推荐实现略复杂

七、总结一句话

回文链表的核心是 左右对称
你可以用数组存储、用栈回溯,或者直接在链表内部用指针完成空间优化。
理解结构关系比死记代码更重要。

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

相关文章:

  • linux 系统压力测试工具stress使用
  • 铜川做网站电话西安模板网站建设
  • 基于单片机大棚浇水灌溉控制系统Proteus仿真(含全部资料)
  • SQL Server 2019实验 │ 数据库和表的创建、修改与删除
  • 服装制造企业痛点解决方案:EFISH-SBC-RK3588 预测性维护方案
  • 怎么利用自媒体做网站优化招聘网站制作公司
  • 每天五分钟深度学习:基于dropout(随机失活)解决神经网络过拟合
  • 自然语言处理(NLP)之分词
  • 双向数据绑定是什么
  • 全链路智能运维中的业务交易粒度资源消耗追踪技术
  • 开源程序网站百度识图在线网页版
  • 【LABVIEW软件】NI-VISA模块安装教程
  • 【完整源码+数据集+部署教程】害虫识别与分类图像分割系统源码和数据集:改进yolo11-MSBlock
  • 建设部网站公告注册成功怎样自己创造网站
  • 婚纱摄影网站毕业设计php汽车网站建设策划方案
  • mysql实战
  • OpenResty + Lua + Redis 鉴权案例,适用于 x86 和 ARM 架构的 Docker 环境。
  • Redis批量查询的 4 种方式
  • Google Chrome浏览器安装教程 谷歌浏览器离线安装(PC+安卓)附谷歌三件套 安装包!
  • Node.js crypto模块所有 API 详解 + 常用 API + 使用场景
  • 好文与笔记分享 Paris, A Decentralized Trained Open-Weight Diffusion Model
  • 企业网站托管排版设计专业网络营销外包公司
  • 1.5 欧拉集群安装Memcached缓存服务
  • asp.net 开发的网站wordpress付费下载模板
  • 十三、OpenCV中的图像的向上采样和向下采样
  • 一份面向研究人员的强化学习对齐指南:为自定义语言模型实施与评估 PPO 和 DPO
  • 石家庄网站seo网页设计与制作课程定位
  • Python全栈(基础篇)——Day10:后端内容(map+reduce+filter+sorted+实战演示+每日一题)
  • Datawhale OpenAI官方智能体框架202510
  • 25软件测试工作量估算