剑指offer68. 树的最近公共祖先

1. 二叉搜索树的最近公共祖先

判断当前节点的值和两节点的值的大小即可确定$LCA(p, q)$的位置:

如果p q的值都小于当前节点的值,则递归进入当前节点的左子树;
如果p q的值都大于当前节点的值,则递归进入当前节点的右子树;
如果当前节点的值在p q两个节点的值的中间,那么这两个节点的最近公共祖先则为当前的节点。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        int cur = root->val, l = p->val, r = q->val;
        if (cur < l && cur < r) return lowestCommonAncestor(root->right, p, q);
        if (cur > l && cur > r) return lowestCommonAncestor(root->left, p, q);
        return root;
    }
};

2. 任意二叉树的最近公共祖先

递归查询两个节点p q,如果某个节点等于节点p或节点q,则返回该节点的值给父节点。
如果当前节点的左右子树分别包括p和q节点,那么这个节点必然是所求的解。
如果当前节点有一个子树的返回值为p或q节点,则返回该值。(告诉父节点有一个节点存在其子树中)
如果当前节点的两个子树返回值都为空,则返回空指针。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* dfs(TreeNode *u, TreeNode *p, TreeNode *q) {
        if (u == p || u == q || u == NULL) return u;
        TreeNode* parent1 = dfs(u->left, p, q);
        TreeNode* parent2 = dfs(u->right, p, q);
        if (parent1 && parent2) return u;
        return parent1 ? parent1 : parent2;
    }
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        return dfs(root, p, q);
    }
};

 

posted @ 2020-04-09 17:06  betaa  阅读(112)  评论(0编辑  收藏  举报