解题思路:
暴力,递归
1 定义辅助函数,判断以root为节点的树中是否包含p或q节点。
2 假如root不等于p或者q节点,那么看看左子树包含它们吗,右子树包含它们吗;
a 假如左右子树都包含节点,说明各包含一个,返回当前root就可以了;
b 假如只有左子树包含,说明两个节点都在左子树,那么就递归到左子树;
c 假如只有右子树包含,说明两个节点都在右子树,那么就递归到右子树;
假如遇到root为p、q本身为最近公共祖先的情况,返回root本身;
有人会考虑到root是p、q本身,那另一个节点可能在右边啊,这里不会,因为遇到这种情况之前,会遇到上面的a情况,已经return 结果了。(所以产生了下面的第二个版本的代码)
/**
* 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) {
//假如root等于p或者q,那么只要看另一个节点是否在root的左右子树中,在的话返回root
if(root==p||root==q){
bool flag=hasNode(root->left,p,q)
||hasNode(root->right,p,q);
if(flag)
return root;
}
//假如root不等于p和q,判断是否在p、q是否分别在左右子树,是的话root就是最近公共祖先
TreeNode* node;
if(root!=p&&root!=q){
bool flag1=hasNode(root->left,p,q);
bool flag2=hasNode(root->right,p,q);
if(flag1&&flag2)
return root;
//假如只有flag1为真,说明p、q都在左子树,在左子树找
if(flag1&&!flag2)
node=lowestCommonAncestor(root->left,p,q);
//假如只有flag2为真,说明p、q都在右子树,在右子树找
if(flag2&&!flag1)
node=lowestCommonAncestor(root->right,p,q);
}
return node;
}
//辅助函数,判断以root为根的树中是否有p、q节点
bool hasNode(TreeNode*root,TreeNode* p, TreeNode* q){
if(root==p||root==q) return true;
if(!root)return false;
bool flag1=hasNode(root->left,p,q);
bool flag2=hasNode(root->right,p,q);
return flag1||flag2;
}
};
版本2
/**
* 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) {
//假如root不等于p和q,判断是否在p、q是否分别在左右子树,是的话root就是最近公共祖先
TreeNode* node=root;
if(root!=p&&root!=q){
bool flag1=hasNode(root->left,p,q);
bool flag2=hasNode(root->right,p,q);
if(flag1&&flag2)
return root;
//假如只有flag1为真,说明p、q都在左子树,在左子树找
if(flag1&&!flag2)
node=lowestCommonAncestor(root->left,p,q);
//假如只有flag2为真,说明p、q都在右子树,在右子树找
if(flag2&&!flag1)
node=lowestCommonAncestor(root->right,p,q);
}
return node;
}
//辅助函数,判断以root为根的树中是否有p、q节点
bool hasNode(TreeNode*root,TreeNode* p, TreeNode* q){
if(root==p||root==q) return true;
if(!root)return false;
bool flag1=hasNode(root->left,p,q);
bool flag2=hasNode(root->right,p,q);
return flag1||flag2;
}
};