

思路:递归解决(时间效率差)
如果结点p和q分别在左右子树,或者根结点为两个结点中一个,则说明当前根结点为最近公共祖先
创立一个递归函数判断两个结点是否在两个子树中:
递归结束条件:传入结点为NULL
前序遍历树,如果传入结点在子树中,返回1
int bothAreChildren(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
if((isInLeft(root->left, p) && isInRight(root->right, q)) || (isInLeft(root->left, q) && isInRight(root->right, p)))
return 1;
return 0;
}
int isInLeft(struct TreeNode* root, struct TreeNode* key) {
if(!root)
return 0;
if(root == key)
return 1;
return isInLeft(root->left, key) || isInRight(root->right, key);
}
int isInRight(struct TreeNode* root, struct TreeNode* key) {
if(!root)
return 0;
if(root == key)
return 1;
return isInLeft(root->left, key) || isInRight(root->right, key);
}
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
if(root == p || root == q || bothAreChildren(root, p, q)) {
return root;
}
if(isInLeft(root->left, p))
return lowestCommonAncestor(root->left, p, q);
return lowestCommonAncestor(root->right, p, q);
}

解题思路:回溯解决
后序遍历自身就是回溯算法
递归结束条件:结点本身等于p、q其中之一或者NULL
struct TreeNode* lowestCommonAncestor(struct TreeNode* root, struct TreeNode* p, struct TreeNode* q) {
if(root == p || root == q || !root)
return root;
struct TreeNode* left = lowestCommonAncestor(root->left, p, q);
struct TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left && right)
return root;
if(left && !right)
return left;
if(right && !left)
return right;
return NULL;
}
