1. 程式人生 > >【未完】最近公共父節點(LCA)

【未完】最近公共父節點(LCA)

1.如果只需要求一對,最簡單的方法是使用遞迴查詢。判斷要查詢的結點u,v是否同在左子樹(向下查詢)、右子樹(向下查詢)或左右子樹都有(根節點即為最近公共父節點)。

class Solution {
public:
    TreeNode * lowestCommonAncestor(TreeNode * root, TreeNode * A, TreeNode * B) {
        if (root==NULL || root==A || root==B) return root;
        TreeNode* left=lowestCommonAncestor(root->left,A,B);
        TreeNode* right=lowestCommonAncestor(root->right,A,B);
        if (left!=NULL && right!=NULL) return root;
        else if (left==NULL) return right;
        else if (right==NULL) return left;
    }
};

以下三種方法使用鄰接矩陣的方式實現。

2.Tarjan(離線)演算法,這個演算法可以一次求多組結點的最近公共父節點。時間複雜度(n+q)。
Tarjan演算法的核心思想使用了深度優先搜尋和並查集的思路。f是並查集的輔助陣列,f和ancestor都是查詢過程中的動態陣列。深度優先在不斷記錄,當前是基於哪個節點,在找這個節點的孩子,當搜尋到這個節點且另一個節點已經被遍歷到的時候,當前基於的結點正好是兩者的公共祖先。[Tarjan’s LCA方法需要通過DFS實現,如果要獲得 P 和 Q 兩個節點的LCA,在DFS遍歷過程中(假如先遍歷到 P

 節點,再遍歷到 Q ,並且是中序遍歷),那麼在遍歷完 Q 時,兩者的LCA就是 P 節點沿著 parent域一直向上直到第一個未遍歷完成的節點。]
檢視程式碼

3.DFS+ST(線上)演算法。時間複雜度O(logn)~O(nlogn)。

4.倍增算演算法。時間複雜度O(logn)~O(nlogn)。