简体   繁体   English

找到两个树节点的最低共同祖先,而不参考根?

[英]find lowest common ancestor of two Tree nodes, without reference to root?

class TreeNode {
    TreeNode parent;
    TreeNode left;
    TreeNode right;

    // other data fields omitted - not relevant
}

You are given two nodes p , and q , how do you find the lowest common ancestor?给定两个节点pq ,如何找到最低的共同祖先? (Assume they both belong in a very large tree) (假设它们都属于一棵非常大的树)

You do NOT have reference to the root of the tree.您没有对树根的引用。

What is the most efficient way to do this?执行此操作的最有效方法是什么? So far, the only idea I have was to到目前为止,我唯一的想法是

(1) pick a node p (doesn't matter which) (1) 选择一个节点 p(哪个无关紧要)

(2) search left sub tree of p, if see q, return p (2) 搜索p的左子树,如果看到q,则返回p

(3) else search right sub tree of p, if see q, return p (3) else 搜索p的右子树,如果看到q,则返回p

(4) else go one level to parent and search the sub-tree that doesn't contain p, if found q, return parent (4) else 上一级到parent,搜索不包含p的子树,如果找到q,则返回parent

(5) else, go up one level again, repeat (4) (search the sub tree that doesnt contain this parent) (5) 否则,再上一层,重复(4)(搜索不包含该父级的子树)

This seems extremely inefficient.这似乎非常低效。 Any better algorithm?有什么更好的算法吗?

Do you have extreme restrictions on the amount of RAM you're allowed to use?您是否对允许使用的 RAM 量有极端限制? If not, I'd propose something like this:如果没有,我会提出这样的建议:

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()

The intuitive idea is as follows.直观的想法如下。 We start at both nodes at the same time.我们同时从两个节点开始。 In every iteration of the loop, we take one step up from both of the nodes.在循环的每次迭代中,我们从两个节点都向上一步。 Whenever we see a node, we put it in our map (which should have O(1) insertion and retrievals / checking if it's already in there).每当我们看到一个节点时,我们就把它放在我们的地图中(它应该有 O(1) 次插入和检索/检查它是否已经在那里)。 When we encounter a node that we've already put in the map, that must be our solution.当我们遇到一个我们已经放在地图中的节点时,那一定是我们的解决方案。

This code should never run for more than max(d_p, d_q) iterations, where d_p and d_q denote the depth levels in the tree that p and q are at, respectively.此代码不应运行超过max(d_p, d_q)次迭代,其中d_pd_q分别表示pq在树中的深度级别。 This will especially be a large advantage if both nodes happen to be rather close to the root.如果两个节点碰巧都非常靠近根,这将是一个很大的优势。 It also means that the code even works for an infinite tree (whereas your solution would get stuck in an infinite loop).这也意味着该代码甚至适用于无限树(而您的解决方案将陷入无限循环)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果不是树中的所有这些节点,Python会在二叉树中找到两个节点的最低共同祖先 - Python find lowest common ancestor of two nodes in a binary tree if not all of these nodes in the tree 从邻接表中找到两个节点的最低共同祖先 - Find the lowest common ancestor of two nodes from adjacency list 在从两个目标节点开始遍历祖先树时,我可以标记我在递归调用中看到的节点以找到它们的最低共同祖先吗? - While traversing an ancestor tree starting from two target nodes, can I mark nodes I've seen in recursive calls to find their lowest common ancestor? 如何找到一棵二叉树的最低共同祖先? - how to find lowest common ancestor of a nary tree? 树中两片叶子的最低共同祖先 - Lowest common ancestor of two leaves in a tree 一元树中多个节点的最低公共祖先 - Lowest Common Ancestor of multiple nodes in a n-ary tree 查找树中两个节点的最小公共祖先 - Finding the least common ancestor of two nodes in a tree 在Java中找到两个节点的最小公祖 - Find least common ancestor of two nodes in java 给定两个节点的共同祖先的算法 - Algorithm to find common ancestor of two nodes given 涉及根节点的最低公共祖先(LCM) - Lowest Common Ancestor (LCM) involving root node
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM