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
list[left] == list[right]?
返回 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) 高效且空间最优
相关推荐
沉在嵌入式的鱼10 分钟前
温度嵌入式软件算法补偿方案及步骤
stm32·单片机·算法·温度传感器·温度补偿
岛雨QA12 分钟前
数据结构和算法概述「Java数据结构与算法学习笔记1」
数据结构·算法
网小鱼的学习笔记14 分钟前
leetcode328:奇偶链表
数据结构·链表
菜鸡儿齐14 分钟前
leetcode-有效的括号
linux·算法·leetcode
We་ct20 分钟前
LeetCode 102. 二叉树的层序遍历:图文拆解+代码详解
前端·算法·leetcode·typescript
历程里程碑20 分钟前
26信号处理一:从闹钟到进程控制的奥秘
linux·运维·服务器·开发语言·c++·算法·排序算法
Gofarlic_OMS21 分钟前
LS-DYNA许可证全局状态及集群计算资源使用可视化监控大屏
运维·开发语言·算法·matlab·自动化
载数而行52023 分钟前
算法系列4之插入排序
数据结构·c++·算法·排序算法
会员果汁24 分钟前
二分搜索-C
c语言·算法