1. 题目

描述

给定一个链表,请判断该链表是否为回文结构。

回文是指该字符串正序逆序完全一致。

数据范围: 链表节点数 0≤n≤10^5^,链表中每个节点的值满足 ∣val∣≤10^7^

示例1

输入:

{1}

返回值:

true

示例2

输入:

{2,1}

返回值:

false

说明:

2->1     

示例3

输入:

{1,2,2,1}

返回值:

true

说明:

1->2->2->1     

2. 解题思路

判断一个链表是否为回文结构,可以先将链表从中间分为两部分,对后半部分进行反转。之后依次对比前半部分链表与后半部分反转之后的节点值。难点在于如何找到中间节点(链表节点数量可能为偶数,也可能为奇数)。链表的反转参考前期的文章《可视化图解算法:反转链表》。

假如有两个链表,结构如下图所示:


步骤一:通过快慢指针分割链表(链表分割为:左右两部分)。
快慢指针变量的定义如下:

注意:fast初始化时指向的节点为slow的下一个节点。
当节点数量为偶数时,fast.next==Null,停止查找。slow.next为后半部分链表的起始点。


当节点数量为奇数时,fast==Null,停止查找。slow节点为中间节点,slow.next为后半部分链表的起始点(前半部分多一个节点)。


步骤二:反转后半部分链表。


步骤三:前后两部分链表节点值对比(判断节点值是否相等)。

如果文字描述的不太清楚,你可以参考视频的详细讲解。

3. 编码实现

核心伪代码如下:

函数 判断回文链表(head: 链表节点) -> 布尔值:
    // 步骤1: 使用快慢指针分割链表
    fast = head.next
    slow = head
    当 fast 不为空 且 fast.next 不为空:
        fast = fast.next.next  // 快指针每次移动两步
        slow = slow.next       // 慢指针每次移动一步
    
    new_node = slow.next       // 后半部分链表的起点
    slow.next = 空             // 断开链表,分割为左右两部分
    left = head                // 左半部分头节点
    
    // 步骤2: 反转右半部分链表
    right = 反转链表(new_node)  // 调用反转链表函数
    
    // 步骤3: 比较左右两部分的节点值
    当 right 不为空:
        如果 right.val != left.val:
            返回 False
        right = right.next    // 右半部分指针后移
        left = left.next      // 左半部分指针后移
    返回 True                  // 所有节点值匹配,是回文

具体完整代码你可以参考下面视频的详细讲解。

4.小结

判断一个链表是否为回文结构,可以先将链表从中间分为两部分,对后半部分进行反转。之后依次对比前半部分链表与后半部分反转之后的节点值。难点在于找到中间节点(可以通过快慢指针查找到中间节点)。

更多数据结构与算法视频讲解,你可以从以下地址找到:

Python编码实现:https://www.bilibili.com/cheese/play/ep1509965
Java编码实现:https://www.bilibili.com/cheese/play/ep1510007
Golang编码实现:https://www.bilibili.com/cheese/play/ep1509945

对于链表的相关操作,我们总结了一套【可视化+图解】方法,依据此方法来解决链表相关问题,链表操作变得易于理解,写出来的代码可读性高也不容易出错。具体也可以参考视频详细讲解。

今日佳句:路虽远行则将至,事虽难做则必成。


好易学数据结构
1 声望0 粉丝