Lowest Common Ancestor of a Binary Tree
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.
好巧,我在Lowest Common Ancestor of a Binary Search Tree的解法一,
就是这题的解法。
深度遍历到节点p时,栈中的所有节点即为p的从根开始的祖先序列。
因此只需要比较p、q祖先序列中最后一个相同的祖先即可。
/**
* 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) {
// special cases
if(root == NULL)
return NULL;
if(p == root || q == root)
return root;
if(p == q)
return p; vector<TreeNode*> vp;
vector<TreeNode*> vq;
stack<TreeNode*> stk;
unordered_map<TreeNode*, bool> m; //visited
stk.push(root);
m[root] = true;
while(!stk.empty())
{
TreeNode* top = stk.top();
if(top->left && m[top->left] == false)
{
stk.push(top->left);
m[top->left] = true;
if(top->left == p)
{
vp = stkTovec(stk);
if(!vq.empty())
break;
}
if(top->left == q)
{
vq = stkTovec(stk);
if(!vp.empty())
break;
}
continue;
}
if(top->right && m[top->right] == false)
{
stk.push(top->right);
m[top->right] = true;
if(top->right == p)
{
vp = stkTovec(stk);
if(!vq.empty())
break;
}
if(top->right == q)
{
vq = stkTovec(stk);
if(!vp.empty())
break;
}
continue;
}
stk.pop();
}
int i = ;
for(; i < vp.size() && i < vq.size(); i ++)
{
if(vp[i] != vq[i])
break;
}
return vp[i-];
}
vector<TreeNode*> stkTovec(stack<TreeNode*> stk)
{
vector<TreeNode*> v;
while(!stk.empty())
{
TreeNode* top = stk.top();
stk.pop();
v.push_back(top);
}
reverse(v.begin(), v.end());
return v;
}
};