234. 回文链表 - 力扣(LeetCode)
·
题目:
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:

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

输入:head = [1,2] 输出:false
提示:
-
链表中节点数目在范围
[1, 105]内 -
0 <= Node.val <= 9
思路如下:
这道题要判断一个链表是不是回文数,直观的判断方法为:将链表的后半段反转。然后将反转后的链表与前半段未反转的链表做比较,直到中间节点如果对应相同,则为回文数。
因此重点在于如何找到后半段要反转的链表,这里我们采用之前学习的快慢指针方法,slow 所指的节点即为中间节点,之后则为后半段链表。接着将后半段链表反转,最后进行比较即可。
题解如下:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def isPalindrome(self, head: Optional[ListNode]) -> bool:
# 使用快慢指针找到链表的中点
slow = fast = head
pre = None
# 快指针每次走两步,慢指针每次走一步,当快指针走到末尾时,慢指针刚好在中间
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# 反转链表的后半部分
while slow:
temp = slow.next # temp 指向当前节点的下一个节点
pre = slow # 将当前节点作为反转后的链表的 头节点
slow = temp # 慢指针移动到下一个节点
# 比较反转后的后半部分和前半部分是否相同
while pre:
if pre.val != head.val:
return False
pre = pre.next # 移动反转后的链表指针
head = head.next # 移动原链表的指针
return True
题解示例:
初始链表 链表结构为:1 -> 2 -> 3 -> 2 -> 1 # 找到链表中点 # 初始化指针: slow 和 fast 都指向头节点 1。 pre 初始化为 None。 第一次循环: fast 和 fast.next 都存在(fast 指向 1,fast.next 指向 2)。 slow 移动到下一个节点 2。 fast 移动两步到节点 3。 第二次循环: fast 和 fast.next 都存在(fast 指向 3,fast.next 指向 2)。 slow 移动到下一个节点 3。 fast 移动两步到节点 1。 第三次循环: fast.next 不存在(fast 指向 1,fast.next 为 None)。 循环结束。 此时,slow 指向节点 3,fast 指向节点 1。 # 反转后半部分链表 # 初始化: slow 指向节点 3。 pre 为 None。 第一次循环: temp = slow.next:temp 被赋值为 slow.next,即节点 2。 pre = slow:pre 指向节点 3。 slow = temp:slow 移动到节点 2。 第二次循环: temp = slow.next:temp 被赋值为 slow.next,即节点 1。 pre = slow:pre 指向节点 2。 slow = temp:slow 移动到节点 1。 第三次循环: temp = slow.next:temp 被赋值为 slow.next,即 None。 pre = slow:pre 指向节点 1。 slow = temp:slow 变为 None。 此时,反转后的后半部分链表为 1 -> 2 -> 3,pre 指向节点 1。 # 比较前后两部分链表# 初始化: pre 指向节点 1。 head 指向原链表的头节点 1。 第一次循环: 比较 pre.val 和 head.val:1 == 1,相等。 pre 移动到下一个节点 2。 head 移动到下一个节点 2。 第二次循环: 比较 pre.val 和 head.val:2 == 2,相等。 pre 移动到下一个节点 3。 head 移动到下一个节点 3。 第三次循环: 比较 pre.val 和 head.val:3 == 3,相等。 pre 移动到下一个节点 None。 head 移动到下一个节点 None。 循环结束: 当 pre 变为 None 时,循环结束。所有比较都通过,函数返回 True,表示该链表是回文的。
逻辑梳理:
-
找到链表中点:
-
使用快慢指针法,快指针(fast)每次移动两步,慢指针(slow)每次移动一步。当快指针到达链表末尾时,慢指针刚好到达链表的中间位置。
-
-
反转后半部分链表:
-
从中间节点开始,逐个将节点从原链表中取出,并将其插入到新链表的头部,从而实现反转。
-
-
比较前后两部分链表:
-
将反转后的后半部分链表与原链表的前半部分逐个节点比较,如果所有对应节点的值都相等,则链表是回文的;否则不是。
-
更多推荐
所有评论(0)