题解:
递归三部曲:
1、确定递归函数返回值以及参数
参数为三个树结点,返回值为树结点,因为需要返回公共祖先
2、确定终止条件
如果找到了结点p或者q,或者遇到了空结点就返回
3、确定单层递归逻辑
递归找目标结点,返回
/**
* 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) {
//终止条件
if(root == q || root == p || root == NULL){
return root;
}
//单层递归逻辑
//左子树里找p和q 不为空说明找到了
TreeNode* left = lowestCommonAncestor(root->left,p,q);
//右子树里找p和q 不为空说明找到了
TreeNode* right = lowestCommonAncestor(root->right,p,q);
//左右都不为空 p和q分布在左右子树
if(left!=NULL && right!= NULL){
return root;
}
//左空右不空 右子树找到p和q
if(left==NULL && right!= NULL){
return right;
}else if(left!=NULL && right==NULL){
//左子树找到p和q
return left;
}else{
//没找到 返回空
return NULL;
}
}
};
之前有写,递归函数有返回值就是要遍历某一条边,但这里不仅有发回执,并且要搜索整个树,有返回值的情况下区分搜索一条边和搜索一整棵树:
//搜索一条边 递归找到立即返回
if(递归函数(root->left)) return;
if(递归函数(root->right)) return;
//搜索整个树
left = 递归函数(root->left);
right = 递归函数(root->right);
left与right的逻辑处理,也就是后序遍历中处理中间结点的逻辑(回溯)