剑指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); } };