二叉树的最近公共祖先

题目:

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

提示:

  • 所有 Node.val 互不相同
  • p != q

思路:

利用后序遍历,设置两个flag,初始值都为false,每个遍历的节点都判断两个flag是否都为true,若是则返回该节点;否则判断是否为p或q,若为p或q则设置对应的flag为true,否则继续遍历整棵树。

class Solution {
public:
    TreeNode* parent;
    TreeNode* LowestCommonAncestorAux(TreeNode* root, TreeNode* p, TreeNode* q)
    {
        if(NULL == root) return NULL;

        TreeNode* left_node = NULL, *right_node = NULL;
        left_node = LowestCommonAncestorAux(root->left, p, q);
        right_node = LowestCommonAncestorAux(root->right, p, q);

        if(NULL != left_node && NULL != right_node) 
        {
            parent = root;
            return root;
        }
        if(root->val == p->val || root->val == q->val)
        {
            if(NULL != left_node || NULL != right_node)
            {
                parent = root;
                return root;
            }
            return root;
        }
        if(left_node) return left_node;
        if(right_node) return right_node;
        return NULL;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        LowestCommonAncestorAux(root, p, q);
        return parent;
    }
};

思路有一点问题,上述代码是看过代码随想录的思路做出来的。使用flag是有问题的,因为只知道已经遍历过两个目标节点了,其余的一概不知。

如:第二个flag为true时,我们需要判断上个节点是否为该节点的子孙节点。若不是,还需要继续遍历,遍历到新的节点后,判断该新节点的左右孩子是否为目标节点,必须遍历,因为不知道节点的位置。。。

使用代码随想录的思路,当遍历到某个节点时,便返回该节点。并在每次递归中都判断,左右孩子是否有返回值,这样就能找到最近的祖先节点。

版本2:

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

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top