【力扣-234. 回文链表 ✨】Python笔记

0 阅读2分钟

判断回文链表:从暴力到最优的算法进阶

本文带你掌握判断回文链表的三种方法,重点解析最优解的“快慢指针+链表反转”技巧,助你轻松应对算法面试。

核心知识点:回文链表的判断策略

回文链表的判断需解决“单向链表无法逆序访问”的问题,常见方法有三种:

  1. 暴力法:将链表转为数组,直接比较正序与逆序。
  2. 递归法:利用递归栈逆序访问节点,但空间复杂度为 O(n)。
  3. 最优解:结合“快慢指针找中点”和“反转后半部分链表”,空间复杂度降为 O(1)。

题目解析:LeetCode 234. 回文链表

题目描述

给定单链表的头节点 head,判断链表是否为回文链表(正读与反读一致)。

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

方法一:暴力法(数组辅助)

将链表节点值存入数组,直接比较正序与逆序。

class Solution:
    def isPalindrome(self, head: Optional[ListNode]) -> bool:
        vals = []
        cur = head
        while cur:
            vals.append(cur.val)
            cur = cur.next
        return vals == vals[::-1]  # 数组正序与逆序比较

复杂度分析:时间 O(n),空间 O(n)。

方法二:最优解(快慢指针+反转链表)

步骤

  1. 找中点:快指针走两步,慢指针走一步,慢指针最终指向中点。
  2. 反转后半部分:从慢指针位置反转链表后半部分。
  3. 双指针比较:头指针与反转后的尾指针同步移动,比较节点值。
  4. 恢复链表:可选,将后半部分链表恢复原状(面试加分项)。
class Solution:
    def isPalindrome(self, head: Optional[ListNode]) -> bool:
        # 1. 找中点:快慢指针
        slow = fast = head
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next

        # 2. 反转后半部分链表
        def reverseList(node):
            pre = None
            cur = node
            while cur:
                temp = cur.next
                cur.next = pre
                pre = cur
                cur = temp
            return pre

        # 3. 比较前后两部分
        left = head
        right = reverseList(slow)
        while right:  # right 长度可能比 left 短(奇数节点时)
            if left.val != right.val:
                return False
            left = left.next
            right = right.next
        return True

复杂度分析:时间 O(n),空间 O(1)。

总结

  • 暴力法:简单但空间复杂度高,适合快速实现。
  • 最优解:结合快慢指针与链表反转,是面试中的标准答案,需熟练掌握。