返回

单链表回文三法详解:步步洞察,游刃有余

见解分享

要鉴定单链表是否是回文的,有三种巧妙且实用的方法,本文将深入探究每种方法的原理和步骤,带领你领略数据结构与算法的魅力。

1. 数组存储前半段值:便捷却不高效

此法通过将链表前半段的值存储在数组中,再依次比较数组元素与链表后半段的值,实现回文判断。

优点:

  • 实现简单,思路清晰。
  • 适用于链表长度较短的情况。

缺点:

  • 数组长度与链表长度成正比,空间消耗较大。
  • 倒序插入数组效率较低。

2. 快慢指针截取:高效简洁

借助快慢指针技巧,可以将链表一分为二,然后对后半段链表进行逆序操作,再逐一对照前后两个链表。

优点:

  • 空间复杂度为 O(1)。
  • 时间复杂度为 O(n),效率较高。
  • 适用于链表长度较长的场景。

缺点:

  • 逆序操作需要额外的空间或时间开销。
  • 若链表元素较多,逆序效率会受到影响。

3. 递归:简洁优雅

递归算法以简洁的方式实现了回文判断,通过不断将链表切分为两部分,递归调用判断各个子部分的回文性。

优点:

  • 实现优雅,代码简洁。
  • 适用于任意长度的链表。

缺点:

  • 递归深度过大时,可能导致栈溢出。
  • 时间复杂度受链表长度影响较大。

示例代码:

# 数组存储前半段值
def is_palindrome_array(head):
    arr = []
    slow = head
    while slow:
        arr.append(slow.val)
        slow = slow.next
    while head and arr:
        if head.val != arr.pop():
            return False
        head = head.next
    return True

# 快慢指针截取
def is_palindrome_fast_slow(head):
    fast = slow = head
    while fast and fast.next:
        fast = fast.next.next
        slow = slow.next
    node = None
    while slow:
        nxt = slow.next
        slow.next = node
        node = slow
        slow = nxt
    while node and head:
        if node.val != head.val:
            return False
        node = node.next
        head = head.next
    return True

# 递归
def is_palindrome_recursion(head):
    def check(left, right):
        if not left or not right:
            return True
        if left.val != right.val:
            return False
        return check(left.next, right.prev)
    return check(head, head)

希望这篇文章能帮助你全面了解单链表回文判断的三种方法,并能让你在实际开发中灵活应用,游刃有余地处理各种链表问题。