簡體   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
}

給定兩個節點pq ,如何找到最低的共同祖先? (假設它們都屬於一棵非常大的樹)

您沒有對樹根的引用。

執行此操作的最有效方法是什么? 到目前為止,我唯一的想法是

(1) 選擇一個節點 p(哪個無關緊要)

(2) 搜索p的左子樹,如果看到q,則返回p

(3) else 搜索p的右子樹,如果看到q,則返回p

(4) else 上一級到parent,搜索不包含p的子樹,如果找到q,則返回parent

(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_pd_q分別表示pq在樹中的深度級別。 如果兩個節點碰巧都非常靠近根,這將是一個很大的優勢。 這也意味着該代碼甚至適用於無限樹(而您的解決方案將陷入無限循環)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM