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 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).”
_______3______
/ \
___5__ ___1__
/ \ / \
6 _2 0 8
/ \
7 4
For example, the lowest common ancestor (LCA) of nodes 5 and 1 is 3. Another example is LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
s思路:
1. LCA. 还是树,树的问题就是如何遍历了。注意是binay tree,不是bst
2. 先来recursive,分别往底层找这两个指针,如果当前层的根指针root等于p或q,则返回p或q,这是recursive的边界情况,也就是元问题,到达元问题后,又逐级回到上层,先左边,后右边,如果左右都有返回,说明在这一级就是LCA,如果只有左边返回了指针,说明左边有一个指针,那就继续把左边的指针往上送,同理,只有右边返回指针,表明右边找到了一个指针,则把右边指针继续往上层送,等回到顶层的时候,就得到最后的LCA。整个过程是pre-order,因为先看当前root是否等于p或q,不等才左右搜索。
3. 搞清楚是pre-order,也就容易用iterative了。调试的时候,发现还不是简单的pre-order,不能按套路来,需要有新的想法。
4. 参考了答案。用的是queue来记录两个节点到root的path,把从child到parent的映射放在map里,然后等两个节点都找到,就把p->root这条path存在unordered_set,然后去查询q是否在这条path上,如果没有,就继续让q回到parent节点,知道找到为止,此时找到的就是LCA.
5. 思考什么时候用queue,什么时候用stack?
//方法1:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//
if(!root||root==p||root==q) return root;
TreeNode* l=lowestCommonAncestor(root->left,p,q);
TreeNode* r=lowestCommonAncestor(root->right,p,q);
if(l&&r) return root;
return l?l:r;
}
};
//方法2:用的改造了的iterative.需要分清什么时候用queue,什么时候用stack!
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//
if(!root) return NULL;
queue<TreeNode*> qq;//iterative不是都要用stack.这道题用stack就搞不定,需要其他辅助
unordered_map<TreeNode*,TreeNode*> mm;//记录child->parent关系
mm[root]=NULL;
qq.push(root);
while(!mm.count(p)||!mm.count(q)){
TreeNode* cur=qq.front();
qq.pop();
if(cur&&cur->left){
qq.push(cur->left);
mm[cur->left]=cur;
}
if(cur&&cur->right){
qq.push(cur->right);
mm[cur->right]=cur;
}
}
unordered_set<TreeNode*> ss;
while(p){
ss.insert(p);
p=mm[p];
}
while(ss.count(q)==0){
q=mm[q];
}
return q;
}
};