题目
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 allow a 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相等, 则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) {
TreeNode* temp;
if(root==NULL)
return NULL;
if(max(p->val, q->val) < root->val) {
return lowestCommonAncestor(root->left, p, q);
} else if(min(p->val, q->val) > root->val) {
return lowestCommonAncestor(root->right, p, q);
} else return root;
}
};
假设给出的不是二分检索树,而是一个普通的二叉树,则需要分别从根结点出发,搜索p,q,保存两条路径,随后比较着两条路径,最后一个相同的结点即为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==null || p==null || q==null) return null;
List<TreeNode> pathp = new ArrayList<>();
List<TreeNode> pathq = new ArrayList<>();
pathp.add(root);
pathq.add(root);
getPath(root, p, pathp);
getPath(root, q, pathq);
TreeNode* lca = null;
for(int i=0; i<pathp.size() && i<pathq.size(); i++) {
if(pathp.get(i) == pathq.get(i)) lca = pathp.get(i);
else break;
}
return lca;
}
private boolean getPath(TreeNode* root, TreeNode* n, List<TreeNode> path) {
if(root==n) {
return true;
}
if(root.left!=null) {
path.add(root.left);
if(getPath(root.left, n, path)) return true;
path.remove(path.size()-1);
}
if(root.right!=null) {
path.add(root.right);
if(getPath(root.right, n, path)) return true;
path.remove(path.size()-1);
}
return false;
}
}