https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.
According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”
Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
Example 1:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3 Explanation: The LCA of of nodes 5 and 1 is 3.
Example 2:
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 Output: 5 Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
Note:
- All of the nodes' values will be unique.
- p and q are different and both values will exist in the binary tree
給你一個binary tree(不是binary search tree喔!!),和其中的兩個點(並假設一定存於在樹中),請問他們的共同祖先中,最接近他們的是誰。
[Solution]
Using DFS to find the path. Find the separate point of path.
Different from the previous question, this is a binary tree, not a binary search tree.
Which mean you cannot decide to go left/right by comparing the value.
You have to execute a DFS to find the path.
Now you know how to find the paths of q and p.
By compare the difference of these two paths, you will find the Lowest Common Ancestor.
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
vector<TreeNode*> pathq;
vector<TreeNode*> pathp;
DFS(root, pathq, q->val);
DFS(root, pathp, p->val);
int i;
for(i=0;i<pathq.size()-1 && i<pathp.size()-1 ;i++){
if(pathq[i+1]!=pathp[i+1])
break;
}
return pathq[i];
}
bool DFS(TreeNode* root, vector<TreeNode*>& path, int target){
if(root==NULL) return false;
path.push_back(root);
if(root->val == target) return true;
if(DFS(root->left , path, target)) return true;
if(DFS(root->right, path, target)) return true;
path.pop_back();
return false;
}
};
[Advance Solution] There is another smart solution in leetcode.
https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/discuss/65226/My-Java-Solution-which-is-easy-to-understand
It is short but faster, because it only scan the tree for one time.
It use a recursive function which :
1.If p and q exist in left and right subtree separately--> return root, this is LCM
2.If one of one subtree have q or q, and another subtree doesn't have any --> return subtree's return value
3.If none of p and q exist in this tree, return NULL
TreeNode* lowestCommonAncestor2(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root==NULL || p == root || q == root) return root;
TreeNode *left = lowestCommonAncestor(root->left, p, q);
TreeNode *right = lowestCommonAncestor(root->right, p , q);
if (left && right) return root;
return left ? left : right;
}