LeetCode Hot100(21/100)——234. 回文链表

文章目录

一、题目理解

题目链接: Palindrome Linked List

题目描述:

给定一个单链表的头节点 head,判断该链表是否为回文链表。

如果链表从前往后与从后往前的节点值序列相同,则认为是回文。

示例:

复制代码
输入:head = [1,2,2,1]
输出:true

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

二、问题分析

我们要判断链表的节点值序列是否是回文结构。

具体而言,若链表的值为 1 -> 2 -> 3 -> 2 -> 1,从前往后与反向的值序列一致,此时返回 true

链表无法直接随机访问,因此不能像数组那样轻易反转或双指针比较,需要借助额外手段。


三、解法一:数组辅助法(最易理解)

核心思路

将链表中的节点值依次存入数组,然后利用数组的下标进行首尾双指针对比。

步骤解析(流程图)





开始
创建空数组 list
遍历链表,将节点值存入 list
设置左右指针 left=0, right=list.size()-1
listleft == listright?
返回 false
left++, right--
left >= right?
返回 true

时间与空间复杂度

  • 时间复杂度: O(n)
    遍历链表一次存入数组,再遍历一半数组比较。
  • 空间复杂度: O(n)
    需要一个额外的数组存储节点值。

Java代码实现

java 复制代码
class ListNode {
    int val;
    ListNode next;
    ListNode(int val) { this.val = val; }
}

public class Solution {
    public boolean isPalindrome(ListNode head) {
        List<Integer> list = new ArrayList<>();
        ListNode node = head;
        while (node != null) {
            list.add(node.val);
            node = node.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;
    }
}

四、解法二:快慢指针 + 反转链表(空间优化)

核心思路

  1. 使用快慢指针 找到链表的中点。
    • 快指针每次走两步,慢指针每次走一步,当快指针到达末尾时,慢指针就在中间位置。
  2. 将后半部分链表反转
  3. 从链表头开始与反转后的后半部分进行逐节点比较
  4. 若全部相同则为回文。

关键步骤图示

找中点
slow
fast
1
2
3
2
1

反转后半部分:
1
2
3
2
1

对比:
反转后半部分 前半部分 反转后半部分 前半部分 若有不同则非回文 比较节点值是否相等 向下一个节点移动

时间与空间复杂度

  • 时间复杂度: O(n)
    找中点 O(n/2),反转 O(n/2),比较 O(n/2)。
  • 空间复杂度: O(1)
    只使用常量指针变量。

Java代码实现

java 复制代码
public 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 firstHalf = head;
        while (secondHalf != null) {
            if (firstHalf.val != secondHalf.val) {
                return false;
            }
            firstHalf = firstHalf.next;
            secondHalf = secondHalf.next;
        }
        return true;
    }

    private ListNode reverseList(ListNode head) {
        ListNode prev = null, curr = head;
        while (curr != null) {
            ListNode nextNode = curr.next;
            curr.next = prev;
            prev = curr;
            curr = nextNode;
        }
        return prev;
    }
}

五、总结

解法 核心思路 时间复杂度 空间复杂度 特点
数组辅助法 用数组保存节点值再比较 O(n) O(n) 简单易理解
快慢指针+反转法 找中点后反转后半部分比较 O(n) O(1) 高效且空间最优
相关推荐
林森lsjs12 分钟前
【日耕一题】5. 青春常数(17届蓝桥杯C++B组第一题)
算法·蓝桥杯
Tisfy15 分钟前
LeetCode 3838.带权单词映射:求和、取模、拼接(附python一行版)
python·算法·leetcode·字符串·题解·模拟·取模
め.21 分钟前
GJK算法实现细节
算法
AI科技星22 分钟前
第六卷:量天尺传奇(几何学)
网络·人工智能·算法·概率论·学习方法·几何学·拓扑学
Y_Bk23 分钟前
第十七届蓝桥杯C/C++A组省赛
c语言·数据结构·c++·算法·蓝桥杯
帅小伙―苏28 分钟前
力扣76最小覆盖子串
算法·leetcode
RH23121138 分钟前
2026.5.24 数据结构 KMP算法实现
数据结构·算法
江屿风40 分钟前
C++图论基础单源最短路-常规版dijkstra算法/堆优化版dijkstra算法/bellman-ford 算法/spfa 算法流食般投喂
开发语言·c++·笔记·算法·图论
浮芷.1 小时前
鸿蒙 6.1 新特性-60fps流畅人物跳跃功能算法深度解析-鸿蒙PC端正弦值计算法
算法·华为·harmonyos·鸿蒙·鸿蒙系统
AI科技星1 小时前
数术工坊·第八卷 大道归一录・番外・下篇 零界封神・万法归元终章
网络·人工智能·算法·几何学·拓扑学