方法:后续遍历
原因:对于每一个结点,该做的事情就是
1、看左右子树中是否包含符合要求的结点。
2、自己是否符合要求。
那么情况分为如下(对于一个结点来说):
1、左右子树都没有满足的结点,自己也不符合
2、左右子树有一个符合,自己不符合
3、左右子树有一个符合,自己符合另外一个(可以确定最终结果)
4、左右子树已经包含要求结点(可以确定最终结果)
代码中返回1表示有符合的情况,返回0表示没有符合的情况或者已经找到结果的情况。
int function(struct TreeNode* root , struct TreeNode** ret,struct TreeNode* p , struct TreeNode* q)
{
if(root != NULL){
//后序遍历
int left = function(root->left , ret , p , q);
int right = function(root->right , ret , p , q);
if(left ^ right == 1)//表示其中一个子树有符合的结点
{
if(root == p || root == q)
{
*ret = root;
return 0;
}
else
return 1;
}
if(root == p || root == q)
return 1;
//情况4
if(left == 1 && right == 1)
{
*ret = root;
return 0;
}
}
return 0;
}
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
// 后续遍历
struct TreeNode** ret = malloc(sizeof(struct TreeNode*));
function(root , ret , p , q);
return *ret;
}