【未完】最近公共父节点(LCA)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/musechipin/article/details/84880263

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

猜你喜欢

转载自blog.csdn.net/musechipin/article/details/84880263