🔥个人主页:guoguoqiang. 🔥专栏:leetcode刷题
二叉树的最近公共祖先
1.通过递归来查找
可分为 在左 右树中,左左树,右右树。三种情况,根据这三种情况来判断。
其中一个结点为根,则他们的公共祖先即为根。
class Solution {
public:
bool isintree(TreeNode* root,TreeNode*x){//查找树中是否存在x
if(root==nullptr)
return false;
return root==x
|| isintree(root->left,x)
|| isintree(root->right,x);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==NULL)
return NULL;
if(root==p||root==q)
return root;
bool pInLeft,pInRight,qInLeft,qInRight;
pInLeft=isintree(root->left,p);//查找p是否在左树中
pInRight=!pInLeft;
qInLeft=isintree(root->left,q);
qInRight=!qInLeft;
if((pInLeft&&qInRight)||(pInRight&&qInLeft)){//如果p在左,q在右,反之也一样,返回根
return root;
}
else if(pInLeft&&qInLeft){//都在左树,递归查找
return lowestCommonAncestor(root->left,p,q);
}
else if(pInRight&&qInRight){//都在右树,递归查找
return lowestCommonAncestor(root->right,p,q);
}
return NULL;
}
};
第二种是通过栈来进行前序来构建路径,然后两个路径找交点,长的先走差距步,然后再来找交点。
class Solution {
public:
bool GetPath(TreeNode* root,TreeNode* x,stack<TreeNode*>& path){//查找x,构建路径
if(root==nullptr)
return false;
path.push(root);
if(root==x)
return true;
if(GetPath(root->left,x,path))
return true;
if(GetPath(root->right,x,path))
return true;
path.pop();
return false;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
stack<TreeNode*> pPath, qPath;
GetPath(root, p, pPath);
GetPath(root, q, qPath);
while(pPath.size() != qPath.size())//让长的先走差距步
{
if(pPath.size() > qPath.size())
pPath.pop();
else
qPath.pop();
}
while(pPath.top() != qPath.top())//寻找交点,交点即为公共祖先
{
pPath.pop();
qPath.pop();
}
return pPath.top();
}
};