找到两个Tree节点的最低共同祖先,而不参考root?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了找到两个Tree节点的最低共同祖先,而不参考root?相关的知识,希望对你有一定的参考价值。
class TreeNode {
TreeNode parent;
TreeNode left;
TreeNode right;
// other data fields omitted - not relevant
}
你有两个节点p
和q
,你如何找到最低的共同祖先? (假设它们都属于一棵非常大的树)
您没有引用树的根。
最有效的方法是什么?到目前为止,我唯一的想法是
(1)选择一个节点p(无所谓)
(2)搜索p的左子树,如果看到q,则返回p
(3)否则搜索p的右子树,如果看到q,则返回p
(4)否则将一个级别转到父级并搜索不包含p的子树,如果找到q,则返回父级
(5)否则,再次上升一级,重复(4)(搜索不包含该父级的子树)
这似乎效率极低。有更好的算法吗?
答案
您对允许使用的RAM数量有极端限制吗?如果没有,我建议这样的事情:
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()
直观的想法如下。我们同时从两个节点开始。在循环的每次迭代中,我们从两个节点向上迈出一步。每当我们看到一个节点时,我们就把它放在我们的地图中(它应该有O(1)插入和检索/检查它是否已经在那里)。当我们遇到一个我们已经放入地图的节点时,那一定是我们的解决方案。
此代码永远不会超过max(d_p, d_q)
迭代运行,其中d_p
和d_q
分别表示p
和q
所在的树中的深度级别。如果两个节点恰好都接近根,那么这将是一个很大的优势。它还意味着代码甚至适用于无限树(而您的解决方案将陷入无限循环)。
以上是关于找到两个Tree节点的最低共同祖先,而不参考root?的主要内容,如果未能解决你的问题,请参考以下文章
如果不是树中的所有这些节点,Python会在二叉树中找到两个节点的最低共同祖先