Given the root and two nodes in a Binary Tree. Find the lowest common ancestor(LCA) of the two nodes.
The lowest common ancestor is the node with largest depth which is the ancestor of both nodes.
Example
For the following binary tree:
4
/ \
3 7
/ \
5 6
LCA(3, 5) = 4
LCA(5, 6) = 7
LCA(6, 7) = 7
思路1:
1. 如果A或B就是根节点,则根节点就是A, B的LCA;
2. 如果A和B都在左子树,则到左子树求LCA;
3. 如果A和B都在右子树,则到右子树求LCA;
4. 否则说明A, B一个在左子树,一个在右子树,则根节点就是A, B的LCA。
5. 另外,如何判断一个节点在子树里?二叉树的遍历。
思路2:
1. 如果A或B就是根节点,则根节点就是A, B的LCA,否则转2;
2. 分治法:
2.1 Divide: 分别在左子树和右子树计算LCA(A, B);
2.2 Conquer: 如果左子树计算的结果和右子树计算的结果都不为空,说明A, B就是根节点的孩子节点,意味着根节点就是A, B的LCA;如果左不为空而右为空,则左子树计算的结果就是A, B的LCA;否则右子树计算的结果是A, B的LCA。
思路2的好处是无须额外判断A, B是否在子树,而是直接从全局的视角来进行分治。
思路1-AC代码(C++):
/** * Definition of TreeNode: * class TreeNode { * public: * int val; * TreeNode *left, *right; * TreeNode(int val) { * this->val = val; * this->left = this->right = NULL; * } * } */
class Solution {
public:
/** * @param root: The root of the binary search tree. * @param A and B: two nodes in a Binary. * @return: Return the least common ancestor(LCA) of the two nodes. */
TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *A, TreeNode *B) {
// write your code here
// BY Huafan
if (root == A || root == B) {
return root;
}
if (isHere(root->left, A) && isHere(root->left, B)) {
return lowestCommonAncestor(root->left, A, B);
} else if (isHere(root->right, A) && isHere(root->right, B)) {
return lowestCommonAncestor(root->right, A, B);
} else {
return root;
}
}
private:
bool isHere(TreeNode *root, TreeNode *node) {
if (root == NULL) {
return false;
}
if (root == node || isHere(root->left, node) || isHere(root->right, node)) {
return true;
}
return false;
}
};
思路2-AC代码(C++):
class Solution {
public:
/** * @param root: The root of the binary search tree. * @param A and B: two nodes in a Binary. * @return: Return the least common ancestor(LCA) of the two nodes. */
TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *A, TreeNode *B) {
// write your code here
// BY Huafan
if (root == NULL) {
return NULL;
}
if (root == A || root == B) {
return root;
}
// divide
TreeNode *left = lowestCommonAncestor(root->left, A, B);
TreeNode *right = lowestCommonAncestor(root->right, A, B);
// conquer
if (left != NULL && right != NULL) {
return root;
}
if (left != NULL) {
return left;
}
if (right != NULL) {
return right;
}
return NULL;
}
};