news 2026/5/23 18:10:22

力扣234.回文链表-反转后半链表

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
力扣234.回文链表-反转后半链表

问题描述

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

示例 :

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

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

解法一:反转后半部分链表(最优解)

这是面试中最常考的方法,时间复杂度 O(n),空间复杂度 O(1)。

算法步骤

  1. 使用快慢指针找到链表的中间节点

  2. 反转链表的后半部分

  3. 比较前半部分和反转后的后半部分

  4. 恢复链表(可选)

代码实现

class Solution { public boolean isPalindrome(ListNode head) { if(head==null||head.next==null){ return true; } ListNode mid=Find_mid(head); ListNode head2=reverse_List(mid); while(head2!=null){ if(head.val!=head2.val){ return false; } head=head.next; head2=head2.next; } return true; } private ListNode reverse_List(ListNode head){//反转链表 ListNode pre=null; ListNode cur=head; while(cur!=null){ ListNode Temp=cur.next; cur.next=pre; pre=cur; cur=Temp; } return pre; } private ListNode Find_mid(ListNode head){//找到中间节点 ListNode slow=head; ListNode fast=head; while(fast!=null&&fast.next != null){ slow=slow.next; fast=fast.next.next; } return slow; } }

关键点分析

  1. 快慢指针找中点

    • 慢指针每次走一步,快指针每次走两步

    • 当快指针到达末尾时,慢指针正好在中点

    • 对于奇数长度链表,慢指针停在中间节点

    • 对于偶数长度链表,慢指针停在中间两个节点的第二个

  2. 反转链表

    • 使用三个指针:pre、curr、Temp,cur指向pre,pre往前移,cur往前移

    • 每次迭代将当前节点的next指向前一个节点

时间复杂度与空间复杂度

  • 时间复杂度:O(n)

    • 找中点:O(n/2) ≈ O(n)

    • 反转后半部分:O(n/2) ≈ O(n)

    • 比较两部分:O(n/2) ≈ O(n)

    • 总时间:O(n)

  • 空间复杂度:O(1)

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

解法二:使用栈

思路

利用栈的后进先出特性,将链表元素入栈,然后依次出栈与链表比较。

代码实现

java

class Solution { public boolean isPalindrome(ListNode head) { if (head == null || head.next == null) { return true; } Stack<Integer> stack = new Stack<>(); ListNode current = head; // 将链表值压入栈中 while (current != null) { stack.push(current.val); current = current.next; } // 比较栈顶元素和链表当前值 current = head; while (current != null) { if (current.val != stack.pop()) { return false; } current = current.next; } return true; } }

复杂度分析

  • 时间复杂度:O(n),需要遍历链表两次

  • 空间复杂度:O(n),需要额外栈空间

解法三:递归

思路

利用递归的调用栈,从链表末尾开始比较。

代码实现

java

class Solution { private ListNode frontPointer; public boolean isPalindrome(ListNode head) { frontPointer = head; return recursivelyCheck(head); } private boolean recursivelyCheck(ListNode currentNode) { if (currentNode != null) { // 递归到链表末尾 if (!recursivelyCheck(currentNode.next)) { return false; } // 比较当前节点值和前端指针的值 if (currentNode.val != frontPointer.val) { return false; } // 前端指针向后移动 frontPointer = frontPointer.next; } return true; } }

复杂度分析

  • 时间复杂度:O(n),需要递归遍历整个链表

  • 空间复杂度:O(n),递归调用栈的空间

解法四:复制到数组 + 双指针

思路

将链表值复制到数组中,然后使用双指针判断数组是否为回文。

代码实现

java

class Solution { public boolean isPalindrome(ListNode head) { // 将链表值复制到数组中 List<Integer> values = new ArrayList<>(); ListNode current = head; while (current != null) { values.add(current.val); current = current.next; } // 使用双指针判断数组是否为回文 int left = 0; int right = values.size() - 1; while (left < right) { if (!values.get(left).equals(values.get(right))) { return false; } left++; right--; } return true; } }

复杂度分析

  • 时间复杂度:O(n)

    • 复制到数组:O(n)

    • 双指针比较:O(n/2) ≈ O(n)

  • 空间复杂度:O(n),需要额外数组存储链表值

常见错误与注意事项

错误1:没有处理奇偶长度差异

java

// 错误示例:没有考虑奇偶长度差异 private ListNode findMiddle(ListNode head) { ListNode slow = head; ListNode fast = head; while (fast != null) { // 错误:应该检查fast.next slow = slow.next; fast = fast.next.next; } return slow; }

修正

java

private ListNode findMiddle(ListNode head) { ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } return slow; }

错误2:反转链表实现错误

修正

java

private ListNode reverseList(ListNode head) { ListNode pre = null; ListNode cur = head; while (cur != null) { ListNode temp = cur.next; cur.next = pre; pre = cur; cur = temp; } return pre; }

扩展:如果要恢复链表怎么办?

如果需要保持链表原样,可以在比较后再次反转恢复:

java

class Solution { public boolean isPalindrome(ListNode head) { if (head == null || head.next == null) return true; // 找到中点 ListNode slow = head, fast = head; while (fast != null && fast.next != null) { slow = slow.next; fast = fast.next.next; } // 反转后半部分 ListNode secondHalf = reverseList(slow); // 比较 ListNode p1 = head, p2 = secondHalf; boolean result = true; while (p2 != null) { if (p1.val != p2.val) { result = false; break; } p1 = p1.next; p2 = p2.next; } // 恢复链表 reverseList(secondHalf); return result; } private ListNode reverseList(ListNode head) { ListNode prev = null, curr = head; while (curr != null) { ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp; } return prev; } }

总结

方法时间复杂度空间复杂度优点缺点
反转后半部分O(n)O(1)空间最优,满足进阶要求修改了原链表结构
使用栈O(n)O(n)实现简单,不修改原链表需要额外空间
递归O(n)O(n)代码简洁递归深度可能较大
复制到数组O(n)O(n)实现简单需要额外空间

推荐使用反转后半部分链表的方法,因为:

  1. 空间复杂度为 O(1),满足进阶要求

  2. 时间复杂度为 O(n),性能良好

  3. 是面试中最常考的解法

相关题目

  1. 反转链表:基础中的基础,必须掌握

  2. 链表的中间结点:快慢指针的经典应用

  3. 回文数字:类似的回文判断问题

  4. 回文字符串:字符串版本的回文判断

掌握这道题的关键在于理解快慢指针和链表反转这两个核心技巧,这两个技巧在链表相关题目中非常常见。

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

专用自动化测试系统赋能飞机系统高效验证与保障

航空工业对安全性、可靠性的要求近乎苛刻&#xff0c;飞机上复杂的综合任务处理系统&#xff08;如航电、飞控、机电管理等&#xff09;的集成验证、性能评估和网络分析&#xff0c;是一项庞大而精密的工程挑战。传统的测试方法往往效率低下、覆盖面有限且易出错。为此&#xf…

作者头像 李华
网站建设 2026/5/22 21:01:33

深入理解C++多态:从概念到原理

深入理解C多态&#xff1a;从概念到原理 一、什么是多态&#xff1f; 多态&#xff08;Polymorphism&#xff09;&#xff0c;顾名思义&#xff0c;就是“多种形态”。在C编程中&#xff0c;它意味着使用同一个接口或函数名&#xff0c;可以执行不同的操作。这大大增强了代码的…

作者头像 李华
网站建设 2026/5/22 4:11:38

HTML 框架:构建网页结构的基础

HTML 框架:构建网页结构的基础 概述 HTML框架(HTML Frames)是HTML文档中用于定义多个子窗口(frame)的容器。它允许在一个HTML文档中嵌入多个独立的HTML页面,每个页面可以在自己的框架中显示。框架的引入是为了解决早期网页设计中布局和内容分离的问题。然而,随着CSS和…

作者头像 李华
网站建设 2026/5/23 18:09:45

2026企业级AI编程工具TOP7:团队协作、安全合规与降本增效的首选

在2025年的AI编程工具市场上&#xff0c;企业级需求正成为竞争焦点。数据显示&#xff0c;全球开发者AI工具使用率已攀升至73%&#xff0c;而企业团队在选择时考虑的核心因素已经从个人效率&#xff0c;转向了团队协作、安全合规与成本控制。01 企业转型&#xff1a;当AI成为团…

作者头像 李华
网站建设 2026/5/16 2:57:43

39、程序性能调优工具全解析

程序性能调优工具全解析 在软件开发过程中,程序性能调优是一个至关重要的环节。本文将详细介绍几种常用的性能调优工具,包括它们的使用方法、适用场景以及优缺点。 1. 使用Valgrind检查指令效率 Valgrind是一款功能强大的工具集,可用于检查内存泄漏和内存损坏问题。这里我…

作者头像 李华
网站建设 2026/5/21 9:54:32

大模型的合规突围:从风险管控到专业赋能

面对大模型备案&#xff0c;不少企业仍陷入“想合规却不知如何落地”的困境&#xff1a;备案材料反复被退回、数据脱敏技术不达标、内容审核机制缺失……这些“合规痛点”不仅拖延了产品上线周期&#xff0c;更可能让企业错失市场先机。 ​一、​​大模型​技术的隐忧 2023 年…

作者头像 李华