Design an algorithm and write code to find the first common ancestor of two nodes in a binary tree. Avoid storing additional nodes in a data structure. NOTE: This is not necessarily a binary search tree.
参考http://hawstein.com/posts/4.6.html
原理是n1和n2必定位于第一个公共祖先的left和right侧。递归直到发现n1和n2位于不同侧的root就是答案。
其中covers函数用来判断n2是否在n1及其子孙路径上, if(covers(root->left, n1) )就可以来判断n1是否在root的左子树上面。
如果n1和n2不在同一侧,那么当前root就是第一个公共祖先。
#include <iostream>
using namespace std;
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
bool covers(TreeNode* n1, TreeNode* n2)
{
if(n1 == NULL) return false;
else if(n1 == n2) return true;
else return covers(n1->left, n2) || covers(n1->right, n2);
}
TreeNode* fisrtComAncestor(TreeNode* root, TreeNode* n1, TreeNode* n2)
{
if(covers(root->left, n1) && covers(root->left, n2))
return fisrtComAncestor(root->left, n1, n2);
if(covers(root->right, n1) && covers(root->right, n2))
return fisrtComAncestor(root->right, n1, n2);
return root;
}
int main()
{
TreeNode * a = new TreeNode(1);
TreeNode * b = new TreeNode(2);
TreeNode * c = new TreeNode(3);
TreeNode * d = new TreeNode(4);
TreeNode * e = new TreeNode(5);
TreeNode * f = new TreeNode(6);
a->left=b;
a->right=c;
b->right=d;
c->left=e;
c->right=f;
TreeNode * ans = fisrtComAncestor(a, b, f);
cout << ans->val << endl;
return 0;
}