查找节点pq的公共祖先
后序遍历:
1. 退出条件,当前节点为空
2. 如果当前节点不为空那么进入它的左右子树查看,是否含有需要查找的节点pq
3. 左右子树皆遍历完毕,现在先查当前节点是否为公共祖先,分为下面四种情况
(1)当前节点恰好的最近祖先,将当前节点给与最终结果,并且将返回值置空,以免出现再次赋值的情况(恰好两个节点分别在左右子树上)
(2) 当前节点为pq中的其中一个,并且另一个在当前节点的左右子树上,那么返回当前节点,并将返回值置空
(3)当前节点为第一次遇到pq中的一个,返回true,表示当前子树中含有一个节点
(4) 其他情况皆返回左子树||右子树的返回值(表名当前字数上右一个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* ans=nullptr;
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
int flag = 0;
lowest(root,p,q,flag);
return ans;
}
bool lowest(TreeNode* root, TreeNode* p, TreeNode* q,int &flag){
if(root==NULL){
return false;
}
bool left = lowest(root->left,p,q,flag);
bool right = lowest(root->right,p,q,flag);
// 后续遍历根节点,自己本身是公共祖先的情况
// 第一种情况,在左子树与右子树上
if(left&&right){
ans = root;
return false;
}else if(left&&(root==p||root==q)||right&&(root==p||root==q)){ // 第二种情况,节点本身就是公共祖先
ans = root;
return false;
}else if(root==p||root==q){ // 第三种情况,找到一个节点
return true;
}else{
return left||right;
}
}
};