Tree 查找两个树节点的最低公共祖先,而不引用根?
您被赋予两个节点Tree 查找两个树节点的最低公共祖先,而不引用根?,tree,binary-tree,lowest-common-ancestor,tree-search,Tree,Binary Tree,Lowest Common Ancestor,Tree Search,您被赋予两个节点p,和q,如何找到最低的共同祖先?(假设它们都属于一棵很大的树) 您没有对树的根的引用 最有效的方法是什么? 到目前为止,我唯一的想法就是 (1) 选择一个节点p(与哪个节点无关) (2) 搜索p的左子树,如果看到q,则返回p (3) 否则搜索p的右子树,如果看到q,则返回p (4) 否则,转到父级并搜索不存在的子树 包含p,如果找到q,则返回父级 (5) 否则,再上一级,重复(4)(搜索 不包含此父级) 这似乎效率极低。有更好的算法吗?您对允许使用的RAM数量有严格限制吗?如果
p
,和q
,如何找到最低的共同祖先?(假设它们都属于一棵很大的树)
您没有对树的根的引用
最有效的方法是什么?
到目前为止,我唯一的想法就是
(1) 选择一个节点p(与哪个节点无关)
(2) 搜索p的左子树,如果看到q,则返回p
(3) 否则搜索p的右子树,如果看到q,则返回p
(4) 否则,转到父级并搜索不存在的子树
包含p,如果找到q,则返回父级
(5) 否则,再上一级,重复(4)(搜索
不包含此父级)
这似乎效率极低。有更好的算法吗?您对允许使用的RAM数量有严格限制吗?如果不是,我会提出如下建议:
class TreeNode {
TreeNode parent;
TreeNode left;
TreeNode right;
// other data fields omitted - not relevant
}
直觉的想法如下。我们同时从两个节点开始。在循环的每次迭代中,我们从两个节点向上走一步。每当我们看到一个节点,我们就把它放在我们的映射中(应该有O(1)个插入和检索/检查它是否已经在那里)。当我们遇到一个已经放在地图上的节点时,这一定是我们的解决方案
此代码的运行时间不得超过
max(d_p,d_q)
迭代次数,其中d_p
和d_q
分别表示树中p
和q
所处的深度级别。如果两个节点恰好都非常靠近根,这将是一个很大的优势。这还意味着代码甚至可以用于无限树(而您的解决方案将陷入无限循环)。从p
一次遍历一个步骤(并且只有一个父级)。在每个步骤中,完全向左和向右递归,查找q
节点。如果找到,则返回true,否则返回false。一路上,当您触摸每个节点时,将其标记为dirty,这样您就不必在更高级别重复递归。
visited_nodes = {} // something like a HashMap, with O(1) insert and retrieval
node1 = p
node2 = q
while True:
if node1 == null and node2 == null: // the nodes don't seem to be in same tree
return null // or failure or anything like that
if node1 is not null:
if node1 in visited_nodes: // node1 must be lowest common ancestor
return node1
else:
visited_nodes.insert(node1) // remember that we've seen this node
node1 = node1.getParent()
if node2 is not null:
if node2 in visited_nodes: // node2 must be lowest common ancestor
return node2
else:
visited_nodes.insert(node2) // remember that we've seen this node
node2 = node2.getParent()