【问题标题】:How does the back pointer move when using recursion to check a palindrome?使用递归检查回文时,反向指针如何移动?
【发布时间】:2021-06-11 07:10:45
【问题描述】:

我找到了一个递归解决方案来检查一个链表是否是回文:

def isPalindrome(self, head: ListNode) -> bool:

    self.front_pointer = head

    def recursively_check(head):
        if head:
            if not recursively_check(head.next):
                return False
            if self.front_pointer.val != head.val:
                return False
            self.front_pointer = self.front_pointer.next
        return True

    return recursively_check(head)

'if head' 声明之后:

当“recursively_check(head.next)”指向 None 时,为什么我们在第一个 if 语句中返回 False?这样就好了,不是吗?因为它只是意味着我们已经到达链表的末尾,还是我读错了?

对于第二个 if 语句,这种说法是有道理的——在我看来,这是检查第一个节点 front_pointer 和最后一个节点 head 是否相同?

那么我们只是简单地将最初指向链表头部的front_pointer移动到下一个要检查的节点?但是虽然我理解这一点,但从后端来看,我们如何从最后一个节点移动到倒数第二个节点?

最后,为什么我们要返回递归调用recursively_check()?我不知道我们什么时候会到达这个代码——因为我们到达这里时会返回 True 或 False,不是吗?

【问题讨论】:

  • 您是否测试过这段代码,或者您只是假设它可以工作?
  • 我已经对其进行了测试,现在它可以工作了——唯一缺少的是最后一次“递归检查”中的参数“head”。
  • 我建议你调试它:在每次调用recursively_check时检查head和self.front_pointer的值。诀窍有点微妙。考虑将head 作为函数参数并将front_pointer 作为包含对象的属性的效果。并尝试将自己限制在每个帖子的一个特定问题上。

标签: python linked-list palindrome


【解决方案1】:

在if head 语句之后:当recursively_check(head.next) 指向None 时,为什么我们要为第一个if 语句返回False?这样就好了,不是吗?因为它只是意味着我们已经到达链表的末尾,还是我读错了?

recursively_check(head.next) 不“指向None”。它是一个布尔值:要么是True,要么是False。将True 解释为“到目前为止它看起来像回文”,并将False 解释为“这绝对不是回文”。

这个特定的return False 旨在通过在递归调用树中检测到更深 的故障退出递归。在这里,我们只是将该消息传递给调用者,调用者也会这样做。它与到达列表末尾无关。它是由递归树中更深层次的差异触发的。

对于第二个 if 语句,这种说法是有道理的——在我看来,它是检查第一个节点 front_pointer 和最后一个节点 head 是否相同?

是的,第一次执行时就是这样。

那么我们只是简单地将最初指向链表头部的front_pointer移动到下一个要检查的节点?

是的

虽然我理解这一点,但从后端来看,我们如何从最后一个节点移动到倒数第二个节点?

这由递归处理。每个递归调用都得到自己的head 变量。当我们用head.next 对其进行初始化时,deeper 递归调用将在列表中将其head 初始化进一步。

这意味着,当我们回溯超出递归级别时,我们会进入一个将其head 变量设置为previous节点的执行上下文,而不是更深层次的调用正在使用的一个(正如我们给它的head.next)。因此,仅通过退出当前执行上下文,我们就会退回到先前的值head,这对应于在列表中后退一步。但是请注意,我们这里的head 变量与列表中的节点一样多。它们都在递归调用堆栈中堆叠在一起。通过展开调用堆栈,我们可以使用之前的 head 变量。

最后,为什么我们返回递归调用recursively_check()?我不知道我们什么时候会到达这个代码——因为我们到达这里时会返回 True 或 False,不是吗?

我们立即达成此声明。当我们到达那里时,它上面的函数还没有执行。正是这条语句将启动递归,我们需要从该调用中获取信息,而该信息就是我们想要返回的信息。

这是isPalindrome 的唯一return 语句。其他 return 语句仅服务于 recursively_check。他们不会为isPalindrome 执行退货。

每次我们退出recursively_check 的嵌套执行时,我们都会多测试一对节点。如果我们发现价值差异,我们开始返回False。如上所述,从那时起,False 将成为 recursively_check 的所有未完成调用的返回值,包括直接在 isPalindrome 中进行的调用。

另一方面,只要比较相等,每个嵌套的recursively_check 调用都会返回一个True。如果结果证明比较总是相等,那么isPalindrome 对recursively_check 的调用也会得到True 的回复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-09
    • 2021-04-15
    • 1970-01-01
    • 2022-11-10
    • 1970-01-01
    • 2012-03-30
    • 1970-01-01
    • 2019-01-05
    相关资源
    最近更新 更多