题目链接:力扣
目录
该题目的解法有很多中,接下来我会详细讲解其中三种方法。
法一:递归一
代码实现:
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr||root==q||root==p)
return root;
TreeNode* left_son=lowestCommonAncestor(root->left,p,q);
TreeNode* right_son=lowestCommonAncestor(root->right,p,q);
if(right_son==nullptr)
return left_son;
if(left_son==nullptr)
return right_son;
return root;
}
};
详细讲解:
也可以根据代码画递归展开图。
法二:递归二
代码实现:
class Solution {
public:
bool find(TreeNode* root,TreeNode* child)
{
if(root==nullptr)
return false;
if(root==child)
return true;
return find(root->left,child)||find(root->right,child);
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr)
return nullptr;
if(root==p||root==q)
return root;
bool qleft,pleft,qright,pright;
qleft=find(root->left,q);
qright=find(root->right,q);
pleft=find(root->left,p);
pright=find(root->right,p);
if(qleft&&pright||pleft&&qright)
return root;
else if(qleft&&pleft)
{
return lowestCommonAncestor(root->left,p,q);
}
else if(qright&&pright)
{
return lowestCommonAncestor(root->right,p,q);
}
else
return nullptr;
}
};
详细讲解
法三: 保存路径
代码实现:
class Solution {
public:
bool findPath(TreeNode* root,TreeNode* child,vector<TreeNode*>& v)
{
if(root==nullptr)
return false;
v.push_back(root);
if(root==child)
return true;
if((findPath(root->left,child,v)))
{
return true;
}
if((findPath(root->right,child,v)))
{
return true;
}
v.pop_back();//如果找不到,就回溯。
return false;
}
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root==nullptr)
return nullptr;
if(root==p||root==q)
return root;
vector<TreeNode*> v1;//节点p的路劲
vector<TreeNode*> v2;//节点q的路径
findPath(root,p,v1);
findPath(root,q,v2);
while(v1.size()>v2.size())
{
v1.pop_back();
}
while(v1.size()<v2.size())
{
v2.pop_back();
}
int i=v1.size()-1;
while(v1[i]!=v2[i])
{
i--;
}
return v1[i];
}
};
详细讲解:
找到路径后,如何从两个数组得到最近的公共祖先,是容易的,看代码即可理解。