题目描述(中等难度)
算法
(递归)
当我们用递归去做这个题时不要被题目误导,应该要明确一点
这个函数的功能有三个
:给定两个节点p和q
- 如果p和q都存在,则返回它们的公共祖先;
- 如果只存在一个,则返回存在的一个;
- 如果p和q都不存在,则返回NULL
题目说给定的两个节点都存在,那自然还是能用上面的函数来解决
具体思路:
- 如果当前结点root等于NULL,则直接返回NULL
- 如果root等于p或者q,那这棵树一定返回p或者q
- 然后看递归左右子树(因为是递归,使用函数后可以认为左右子树已经算出了结果,用left和right表示
- 此时若left为空,那最终结果只要看right;若right为空,那最终结果只要看left
- 如果left和right都非空,因为只给了p和q两个结点,都非空,说明一边一个,因此root是他们的最近公共祖先
- 如果left和right都为空,则返回空(其实已经包含在前面的情况中了)
时间复杂度是 ,空间复杂度是 :需要系统栈空间
C++代码
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)
return NULL;
// 可认为左右子树已经实现了函数的功能
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(root == p || root == q)
return root;
if(left == NULL)
return right;
if(right == NULL)
return left;
if(left && right) // p和q在两侧
return root;
return NULL; // 必须有返回值
}
};
如果对递归理解的比较透彻,可以发现下面的代码也是对的
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if(root == NULL)
return NULL;
if(root == p || root == q)
return root;
// 可认为左右子树已经实现了函数的功能
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);
if(left == NULL)
return right;
if(right == NULL)
return left;
if(left && right) // p和q在两侧
return root;
return NULL; // 必须有返回值
}
};
写在最后:我的博客主要是对计算机领域所学知识的总结、回顾和思考,把每篇博客写得通俗易懂是我的目标,分享技术和知识是一种快乐 ,非常欢迎大家和我一起交流学习,有任何问题都可以在评论区留言,也期待与您的深入交流(^∀^●)