我一直在Leetcode的讨论标签中查看下面的粘贴代码,我觉得我不完全理解递归。 question是关于在二叉搜索树中找到2个节点的共同祖先。
def lowestCommonAncestor(self, root, p, q):
if p.val < root.val > q.val:
return self.lowestCommonAncestor(root.left, p, q)
if p.val > root.val < q.val:
return self.lowestCommonAncestor(root.right, p, q)
return root
可以向我解释root
是如何更改的,以便在没有更新其值的情况下给出答案吗?我看到root
被传递到main函数(像p
和q
这样的参数),但递归调用只需要root.left
和root.right
。
您是否可以通过解释找到3和5的共同祖先来澄清递归?
_______6______
/ \
___2__ ___8__
/ \ / \
0 _4 7 9
/ \
3 5
Stackoverflow接受的答案here使用递归,但没有回答我的问题。
答案 0 :(得分:1)
这些if
语句会检查q
和p
是否与root
位于同一侧。
首先if
的含义:p
和q
都小于根,所以它们位于左侧。因此,root
不是他们的lowestCommonAncestor
。例如,示例树中的3
和5
。他们属于这种情况。它们都低于6
,因此它们的共同祖先位于主树左侧的某个位置。使用lowestCommonAncestor(root.left, p, q)
继续下一步。
第二:与第一名相同,除了他们现在在右侧。它们都大于root
,因此它们必须在lowestCommonAncestor
中的某处root.right
。
此功能继续进行,直到存在p
和q
不在同一侧的情况。在这种情况下,root
是lowestCommonAncestor
。
答案 1 :(得分:1)
从树的根开始,p
和q
是您想要获得共同祖先的节点。
例如,当p
是节点3时,q
是节点5. root
是6。
所以p.val < root.val > q.val
将会成立,现在您将致电self.lowestCommonAncestor(root.left, p, q)
。您只是在函数之间移动对象的引用。
现在您的root将是2
(root的左侧),p
和q
是相同的。现在,if p.val > root.val < q.val
将成立,因为3 > 2
和5 > 2
,因此我们会调用self.lowestCommonAncestor(root.right, p, q)
。当我们放入参数root.right
时,这只是对不同对象的引用。只是为了澄清,这不会改变任何对象的值,但它会在当前函数的范围内更改root
的值。
现在你的根将是4
,并且没有条件存在,所以你将返回4
作为你的共同祖先。