234. 回文链表
题目链接
https://leetcode.cn/problems/palindrome-linked-list/description/
解题思路
这题是一个常规中带有一些递归的特殊用法的题目。我们按照递归的一般思路,首先考虑参数和返回值。
题目已经给出了显而易见的参数和返回值。参数为链表中的节点head,返回值为表示一个链表是否为回文链表的bool值。
然后我们思考本层应该做什么,以及如何缩小问题规模。
由于这是链表,我们不可能说通过遍历整个链表来找到回文对应的各个节点来判定是否回文。这样的话用递归完全是在降低性能+炫技。
但我们还想要用递归来做到这样的事情,所以这里就不得不提递归的常见用法--->把递归当成栈。
比如我们的节点是1,2,3,4,5. 我们的递归栈如果是深度优先的,那我们递归栈可以保证对节点的访问是5,4,3,2,1的。
如果此时我们可以设置一个全局变量,顺序遍历1,2,3,4,5,通过与递归栈保存的节点访问顺序进行对比,就可以判定是否为回文。
即:1和5,2和4,3和3,4和2,5和1 一共5对。所以我们缩小规模的方式就是,通过递归栈,先对比两头的元素,然后再往中间靠拢对比对位元素。
想到了这点,那本层应该做什么就呼之欲出了。无非就是将全局变量和递归栈中的变量进行对比,然后对全局变量进行更新。
那么,递归栈是怎么保存节点访问状态的?答案是通过参数。因为我们的返回值只表明了本层是否满足回文。
ok,现在我们开始设计退出条件。
由于我们是深度优先的,所以退出条件就是,当rec_head为空时,返回True。
代码
class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next class Solution: def isPalindrome(self, head) -> bool: real_head = head def dfs(rec_head): if rec_head is None: return True nonlocal real_head last_result = dfs(rec_head.next) cur_result = real_head.val == rec_head.val real_head = real_head.next return last_result and cur_result return dfs(head)
代码二:
# Definition for singly-linked list. # class ListNode: # def __init__(self, val=0, next=None): # self.val = val # self.next = next class Solution: def isPalindrome(self, head: Optional[ListNode]) -> bool: real_head = head def dfs(tail_node): if tail_node is None: return True last_result = dfs(tail_node.next) nonlocal real_head cur_result = real_head.val == tail_node.val real_head = real_head.next return last_result and cur_result return dfs(head)