Skip to main content

234.回文链表

标签: linked-list, two-pointers

难度: Easy

通过率: 54.67%

原题链接: https://leetcode.com/problems/palindrome-linked-list/description/

题目描述

给定一个单链表的头节点,判断该链表是否为回文链表。如果是回文链表,返回 true,否则返回 false

解题思路

要判断一个链表是否为回文,可以使用快慢指针的方法来查找链表的中点,将链表分成两个部分,然后反转后半部分并与前半部分比较。具体步骤如下:

  1. 使用快慢指针找到链表的中点。快指针每次移动两步,慢指针每次移动一步。当快指针到达链表末尾时,慢指针将位于链表中点。

  2. 将链表从中点分为两部分,并反转第二部分链表。例如,对于链表 [1,2,2,1],反转后将为 [1,2][1,2]

  3. 比较前半部分和反转后的后半部分链表节点的值是否相等。如果它们全部相等,则链表是一个回文链表。

  4. 可选:可以在比较后再次反转后半部分链表以恢复链表的原始结构。

代码实现

class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next

class Solution:
def isPalindrome(self, head: ListNode) -> bool:
if not head or not head.next:
return True

# 找到链表中点
slow, fast = head, head
while fast and fast.next:
slow = slow.next
fast = fast.next.next

# 反转后半部分链表
prev, curr = None, slow
while curr:
next_node = curr.next
curr.next = prev
prev = curr
curr = next_node

# 比较前半部分和后半部分
first, second = head, prev
while second: # 只用比较后半部分
if first.val != second.val:
return False
first = first.next
second = second.next

return True

复杂度分析

时间复杂度:O(n)O(n),其中 nn 是链表的长度,因为需要遍历链表两次:一次是找到中点,另一次是反转和比较。

空间复杂度:O(1)O(1),我们只使用了几个指针变量来控制链表节点的过程,没有使用额外的空间。