• 力扣第236题 二叉树的最近公共祖先 c++ 递归和回溯 附注释和简短代码


    题目

    236. 二叉树的最近公共祖先

    中等

    相关标签

       深度优先搜索   二叉树

    给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

    百度百科最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”

    示例 1:

    输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
    输出:3
    解释:节点 5 和节点 1 的最近公共祖先是节点 3
    

    示例 2:

    输入:root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
    输出:5
    解释:节点 5 和节点 4 的最近公共祖先是节点 5因为根据定义最近公共祖先节点可以为节点本身。
    

    示例 3:

    输入:root = [1,2], p = 1, q = 2
    输出:1
    

    提示:

    • 树中节点数目在范围 [2, 105] 内。
    • -109 <= Node.val <= 109
    • 所有 Node.val 互不相同 。
    • p != q
    • p 和 q 均存在于给定的二叉树中。

    思路和解题方法

    算法使用递归方法,对每个节点进行遍历。在遍历过程中,首先判断当前节点是否为NULL或等于p或q节点本身,如果是,则返回当前节点。否则,分别递归遍历左右子树,并将其结果保存在leftright变量中。接下来,对leftright进行判断:

    • 如果leftright都不为NULL,说明当前节点是p和q的最近公共祖先节点,返回当前节点。
    • 如果只有right不为NULL,说明p和q节点都在右子树,返回right节点。
    • 如果只有left不为NULL,说明p和q节点都在左子树,返回left节点。
    • 如果leftright都为NULL,说明p和q节点都不在当前节点的子树中,返回NULL。

    最终返回值即为p和q的最近公共祖先节点。

    复杂度

            时间复杂度:

                    O(n)

    时间复杂度:

    • 遍历整棵二叉树的过程中,我们需要访问每个节点一次,因此时间复杂度为O(n),其中n是二叉树的节点数。

            空间复杂度

                    O(n)

    空间复杂度:

    • 在递归过程中,需要使用递归调用栈来保存每个递归函数的局部变量。在最坏情况下,递归栈的深度等于二叉树的高度。如果二叉树是平衡树,则高度为log(n),其中n为节点数。如果二叉树是非平衡树,则高度可能达到n,比如链表形式的二叉树。因此,空间复杂度为O(h),其中h是二叉树的高度。

    c++ 代码

    1. class Solution {
    2. public:
    3. // 递归函数,用于寻找p和q的最近公共祖先节点
    4. TreeNode* traver(TreeNode* root, TreeNode* p, TreeNode* q) {
    5. // 如果当前节点为空,返回NULL
    6. if (root == NULL) {
    7. return NULL;
    8. }
    9. // 如果当前节点是p或q本身,则返回当前节点
    10. if (root == p || root == q) {
    11. return root;
    12. }
    13. // 递归遍历左子树,寻找p和q的最近公共祖先节点
    14. TreeNode* left = traver(root->left, p, q);
    15. // 递归遍历右子树,寻找p和q的最近公共祖先节点
    16. TreeNode* right = traver(root->right, p, q);
    17. // 根据左右子树的结果进行判断
    18. if (left != NULL && right != NULL) {
    19. // 如果左右子树的结果都不为空,说明当前节点是p和q的最近公共祖先节点
    20. return root;
    21. }
    22. else if (left == NULL && right != NULL) {
    23. // 如果左子树的结果为空,右子树的结果不为空,说明p和q节点都在右子树上
    24. return right;
    25. }
    26. else if (left != NULL && right == NULL) {
    27. // 如果左子树的结果不为空,右子树的结果为空,说明p和q节点都在左子树上
    28. return left;
    29. }
    30. else {
    31. // 如果左右子树的结果都为空,说明p和q节点都不在当前节点的子树中
    32. return NULL;
    33. }
    34. }
    35. // 寻找p和q的最近公共祖先节点
    36. TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    37. // 调用递归函数,返回最近公共祖先节点
    38. return traver(root, p, q);
    39. }
    40. };

    c++优化后的代码

    1. class Solution {
    2. public:
    3. // 寻找p和q的最近公共祖先节点
    4. TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
    5. // 如果当前节点为空,或者当前节点是p或q本身,则返回当前节点
    6. if (root == nullptr || root == p || root == q) {
    7. return root;
    8. }
    9. // 递归遍历左子树,寻找p和q的最近公共祖先节点
    10. TreeNode* left = lowestCommonAncestor(root->left, p, q);
    11. // 递归遍历右子树,寻找p和q的最近公共祖先节点
    12. TreeNode* right = lowestCommonAncestor(root->right, p, q);
    13. // 根据左右子树的结果进行判断
    14. if (left && right) {
    15. // 如果左右子树的结果都不为空,说明当前节点是p和q的最近公共祖先节点
    16. return root;
    17. }
    18. // 如果左子树的结果不为空,则返回左子树的结果
    19. // 如果左子树的结果为空,右子树的结果不为空,则返回右子树的结果
    20. return left ? left : right;
    21. }
    22. };

    小代码满足

    1. class Solution {
    2. public:
    3. TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
    4. if (root == nullptr || root == p || root == q) return root;
    5. TreeNode *left = lowestCommonAncestor(root->left, p, q);
    6. TreeNode *right = lowestCommonAncestor(root->right, p, q);
    7. if (left && right) return root;
    8. return left ? left : right;
    9. }
    10. };

    觉得有用的话可以点点赞,支持一下。

    如果愿意的话关注一下。会对你有更多的帮助。

    每天都会不定时更新哦  >人<  。

  • 相关阅读:
    Apache nginx解析漏洞复现
    【Java8新特性】函数式接口
    基于MindSpore的YOLOv3-DarkNet53网络实现
    【Linux】05.部署Microsoft SQL Server
    通信算法之七十八:无人机反制—精华总结
    .NET周刊【7月第1期 2024-07-07】
    cmd和PyCharm如何调用电脑中有多个版本Python
    学习c++的第十四天
    线性代数_第二章,矩阵
    jQuery 效果- 动画
  • 原文地址:https://blog.csdn.net/jgk666666/article/details/133780541