返回
回文链表的两种优雅解法:双指针与栈的应用
前端
2023-09-21 08:06:57
输入
「链表/双指针」leetcode 234.回文链表(简单)
输出
前言
在计算机科学中,回文链表是一个非常经典的问题。所谓回文链表,即正序和逆序读取完全一致的链表。在许多实际场景中,我们需要判断一个给定的链表是否为回文链表,例如在文本编辑器中检测回文单词或在密码学中验证密码的合法性等。
双指针法
思路
双指针法是一种非常高效且优雅的解决回文链表问题的方法。该方法的核心思想是使用两个指针,一个从链表头节点出发,另一个从链表尾节点出发。这两个指针同时向中间移动,如果在某个时刻这两个指针相遇,则说明链表是回文的。否则,链表不是回文的。
实现步骤
- 初始化两个指针 slow 和 fast,其中 slow 指向头节点,fast 指向尾节点。
- 让 fast 指针一次移动两步,slow 指针一次移动一步。
- 当 fast 指针到达链表尾节点时,停止迭代。
- 将 slow 指针指向链表中间节点。
- 从 slow 指针开始,反转链表的后半部分。
- 比较前半部分和后半部分的元素是否相等。
- 如果所有元素相等,则链表是回文的;否则,链表不是回文的。
代码示例
def is_palindrome_linked_list_with_two_pointers(head):
"""
判断一个链表是否为回文链表。
参数:
head: 链表头节点。
返回:
如果链表是回文的,返回 True;否则,返回 False。
"""
# 初始化两个指针 slow 和 fast,其中 slow 指向头节点,fast 指向尾节点。
slow = head
fast = head
# 让 fast 指针一次移动两步,slow 指针一次移动一步。
while fast and fast.next:
slow = slow.next
fast = fast.next.next
# 将 slow 指针指向链表中间节点。
if fast:
slow = slow.next
# 从 slow 指针开始,反转链表的后半部分。
prev = None
while slow:
next = slow.next
slow.next = prev
prev = slow
slow = next
# 比较前半部分和后半部分的元素是否相等。
while prev:
if prev.val != head.val:
return False
prev = prev.next
head = head.next
# 如果所有元素相等,则链表是回文的;否则,链表不是回文的。
return True
栈法
思路
栈法也是一种非常高效且优雅的解决回文链表问题的方法。该方法的核心思想是使用一个栈来存储链表的前半部分元素。当快指针到达链表尾节点时,我们将栈中的元素与慢指针指向的后半部分元素进行比较。如果所有元素相等,则链表是回文的。否则,链表不是回文的。
实现步骤
- 将链表的前半部分元素压入栈中。
- 从栈顶开始,将栈中的元素与慢指针指向的后半部分元素进行比较。
- 如果所有元素相等,则链表是回文的;否则,链表不是回文的。
代码示例
def is_palindrome_linked_list_with_stack(head):
"""
判断一个链表是否为回文链表。
参数:
head: 链表头节点。
返回:
如果链表是回文的,返回 True;否则,返回 False。
"""
# 将链表的前半部分元素压入栈中。
stack = []
slow = head
fast = head
while fast and fast.next:
stack.append(slow.val)
slow = slow.next
fast = fast.next.next
# 将 slow 指针指向链表中间节点。
if fast:
slow = slow.next
# 从栈顶开始,将栈中的元素与慢指针指向的后半部分元素进行比较。
while stack:
if stack.pop() != slow.val:
return False
slow = slow.next
# 如果所有元素相等,则链表是回文的;否则,链表不是回文的。
return True
结语
回文链表问题是一个非常经典的问题,在计算机科学中有很多应用场景。双指针法和栈法都是解决该问题非常高效且优雅的方法。希望本文对您理解回文链表问题有所帮助。