在过去的几天里,我一直在为树木和蟒蛇而苦苦挣扎 . 大多数情况下,树木的递归给我带来了麻烦 . 我试图解决的问题是在二叉树中找到第一个共同的祖先 . 有很多解决方案可以解决这个问题,但它们都是二叉搜索树,而不是二叉树 . 在二叉树的情况下,节点不是有序的,因此左边小于右边 . 我知道我应该使用哪种方法,但我在递归部分失败:(编辑:问题表明我不能使用额外的数据结构或存储)
class Node:
"""docstring for Node"""
def __init__(self, data):
self.data = data
self.left=None
self.right=None
def findNode(self,target):
if self==None:
return 0
if self.data==target:
return 1
return self.findNode(self.left,target) or self.findNode(self.right,target)
def firstCommonAncestor(self,p,q):
if self==None:
return 0
if self.left.data==p and self.right.data==q:
return self.data
if findNode(self.left,p) and findNode(self.right,q):
return 1
root=Node(2)
root.left=Node(5)
root.right=Node(4)
root.left.left=Node(9)
root.left.right=Node(7)
print firstCommonAncestor(root,9,7)
我编辑了代码以使问题更加清晰 . findNode(self.left,p)和findNode(self.right,q)应返回1,因为两个节点都存在 . 但是,当findNode(self.right,q)没有从根开始搜索时 . 我知道我应该实现递归调用,但我尝试过的所有内容都失败了 . 如果有人可以就我的错误提供一些指示,我们将不胜感激! (第一个共同的祖先尚未实施,所以这并不重要 . 现在它没有做太多事情) . 编辑:这是破解编码面试的一个问题 .
5 回答
(只是为了暗示它为什么不起作用)
搜索y时,它不会返回到根目录 . 你的代码正在做正确的事情 . 您找不到Node(7)的原因是您的数据 .
这是你的树 .
你的x搜索是findNode(Node(5),9),它找到9 .
你的y搜索是findNode(Node(4),7),当然它永远不会找到7
希望有所帮助 .
另一个提示:你的实例方法脱离了类,并且只是普通的全局方法(它不仅仅是缩进的问题,因为你也以错误的方式调用它们) . 这是
findNode
的正确定义:在
findNode
方法中,您还有一个如何调用它的示例 . 您还应该在firstCommonAncestor
方法中修复此问题 .由于树没有订购,你无论如何都要搜索很多 . 由于您不允许使用额外的数据结构,因此您可能会重复进行大量搜索 .
因此,一旦递归到叶节点,然后在返回组合数据上,这可能是最有效的 . 这是O(n),但那么一次搜索也是如此 .
这就是下面的代码试图做的事情 . 搜索方法返回
(a's parent, b's parent)
,如果它们不同,但两者都设置了,那么我们就是共同的祖先 .EDIT : 重新设计的解决方案使其更清晰并解决了评论中的问题
有一个非常有效的解决方案,但有点复杂 . 它涉及钻入树中并跟踪您是否在返回时找到了第一个或第二个值 . 如果在某些时候你发现两个(第一个和第二个)都返回该节点,它将是你的共同祖先 .
这是一个更有效的解决方案,但是如果你有DUPLICATES它不起作用,但它可以帮助你理解并解决重复的情况: