Lowest Common Ancestor of a Binary Search Tree
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes v and w as the lowest node in T that has both v and w as descendants (where we allowa node to be a descendant of itself).”
_______6______ / \ ___2__ ___8__ / \ / \ 0 _4 7 9 / \ 3 5
For example, the lowest common ancestor (LCA) of nodes 2
and 8
is 6
. Another example is LCA of nodes 2
and 4
is 2
, since a node can be a descendant of itself according to the LCA definition.
思路:如果如果p,q均比root小, 则LCA在左子树, 如果p,q均比root大, 则LCA在右子树. 如果一大一小, 则root为LCA.
/**
* 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) {
if((root->val - p->val) * (root->val - q->val) <= 0)
return root; //一大一小
else if(root->val > p->val)
return lowestCommonAncestor(root->left, p, q);
else
return lowestCommonAncestor(root->right, p, q);
}
考虑一般二叉树,而不是bst。
网上的解法一般是通过回溯法先确定到p,q的路径,然后找到他们最后一个相同的顶点即为LCA,在这里提供另一种求解思路。
我们定义个函数:
bool Find(TreeNode* root,TreeNode*p,TreeNode* q)
意为在root为根的树中,寻找p,q两个节点,若找到其中一个,则返回true,否则返回false。
经过简单考虑可以得知1.若祖先节点本身是p或者q,则他本身就是lca;
2.若在左子树中同时找到了p和q,即(!Find(root->right,p,q))为真,则lca在他的左子树中。
else if ((Find(root->left,p,q))&&(!Find(root->right,p,q))) return lowestCommonAncestor(root->left,p,q);
3.若在右子树中同时找到了p和q在lca在他的右子树中
4.若在左子树中找到了p,q中的一个,右子树中找到了p,q中一个,则lca必定是root本身。
代码见下。
/**
* 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) {
if (root==p||root==q) {
return root;
}
else if ((Find(root->left,p,q))&&(Find(root->right,p,q))) return root;
else if ((Find(root->left,p,q))&&(!Find(root->right,p,q))) return lowestCommonAncestor(root->left,p,q);
else if ((!Find(root->left,p,q))&&(Find(root->right,p,q)) ) return lowestCommonAncestor(root->right,p,q);
}
bool Find(TreeNode* root,TreeNode*p,TreeNode* q){
if (root==NULL) return false;
if(root==p||root==q) return true;
else {return(Find(root->right,p,q)|| Find(root->left,p,q));}
}
};