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) 高效且空间最优
相关推荐
hanlin032 小时前
刷题笔记:力扣第84题-柱状图中最大的矩形
笔记·算法·leetcode
青少儿编程课堂3 小时前
威佐夫博弈(双堆取子游戏)解析
c++·python·算法·bfs·信息学竞赛
辰烨chenye7 小时前
LeetCode Hot 100 题解 · 普通数组篇
算法·leetcode·职场和发展
hqyjzsb10 小时前
零 AI 项目经验,学 Python 转型 AI 的正确顺序是什么?
开发语言·人工智能·python·算法·职场和发展·数据挖掘·数据分析
辰烨chenye10 小时前
LeetCode Hot 100 题解 · 二分篇
java·算法·leetcode
微功夫信息技术10 小时前
分层多智能体强化学习驱动的非急救转运公平 - 效率统一调度系统研究与实践
人工智能·学习·算法·动态规划
sanjiaomao33311 小时前
从论文公式到Python实现:用单元测试校验滑动平均算法
python·算法·单元测试
乐迪信息11 小时前
如何通过AI防爆摄像机精准判断船舶超速?
大数据·人工智能·算法·安全·目标跟踪
大圣编蚕12 小时前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
小玮看世界13 小时前
[Python]OD算法在OD实际运用转化参考清单
开发语言·python·算法