数据结构与算法之链表 回文链表 双指针 + 栈 / 反转后半段 判断

数据结构与算法阿木 发布于 5 天前 2 次阅读


摘要:

回文链表是链表数据结构中一个常见的面试题,要求判断一个链表是否为回文结构。本文将围绕这一主题,深入探讨两种常用的解决方案:双指针配合栈和反转后半段链表。通过分析这两种方法的原理、实现过程以及优缺点,帮助读者更好地理解和应用回文链表判断算法。

一、

回文链表是指链表从前往后读和从后往前读都一样的链表。判断一个链表是否为回文结构,是链表操作中的一个经典问题。本文将详细介绍两种解决回文链表判断问题的算法:双指针配合栈和反转后半段链表。

二、双指针配合栈

1. 原理

双指针配合栈的方法利用栈的先进后出(FILO)特性,将链表的前半部分元素依次入栈,然后从链表的后半部分开始遍历,同时从栈中弹出元素进行比较。如果所有比较的元素都相等,则链表为回文结构。

2. 实现代码

python

class ListNode:


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


self.val = val


self.next = next

def is_palindrome(head):


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

将前半部分元素入栈


stack = []


while slow:


stack.append(slow.val)


slow = slow.next

比较栈中的元素和后半部分链表的元素


while stack and head:


if stack.pop() != head.val:


return False


head = head.next

return True


3. 优缺点

优点:空间复杂度较低,只需要一个栈即可。

缺点:时间复杂度为O(n),需要遍历整个链表。

三、反转后半段链表

1. 原理

反转后半段链表的方法是将链表的后半部分反转,然后与前半部分进行比较。如果所有比较的元素都相等,则链表为回文结构。

2. 实现代码

python

class ListNode:


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


self.val = val


self.next = next

def is_palindrome(head):


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

比较前半部分和反转后的后半部分链表


left, right = head, prev


while right:


if left.val != right.val:


return False


left = left.next


right = right.next

return True


3. 优缺点

优点:时间复杂度较低,只需要遍历链表一次。

缺点:空间复杂度较高,需要额外的空间来存储反转后的后半部分链表。

四、总结

本文介绍了两种判断回文链表的算法:双指针配合栈和反转后半段链表。这两种方法各有优缺点,在实际应用中可以根据具体需求选择合适的方法。通过对这两种算法的深入分析,读者可以更好地理解和应用回文链表判断算法。

五、拓展

1. 如何判断一个字符串是否为回文?

2. 如何判断一个字符串是否为回文链表?

3. 如何判断一个二维数组是否为回文矩阵?

通过学习回文链表判断算法,读者可以进一步拓展到其他回文问题的解决方法,提高自己的编程能力。