1123. 最深叶节点的最近公共祖先

文章目录

  • Tag
  • 题目来源
  • 题目解读
  • 解题思路
    • 方法一:递归
  • 写在最后

Tag

【递归】【最近公共祖先】【二叉树】


题目来源

1123. 最深叶节点的最近公共祖先,865. 具有所有最深节点的最小子树 此二题系重复的题目。

1123. 最深叶节点的最近公共祖先_第1张图片

题目解读

题目意思很明确,找出二叉树最深节点的最近公共祖先。二叉树中每个节点的值都是独一无二的。


解题思路

寻找节点的最近公共祖先的一个朴素思想是:记录每一个节点的父节点,然后通过迭代的方式找到节点的最近公共祖先。在本题中需要先找到深度最深的那些节点,这些节点可能是两个节点也能是多个节点,可以预见的是这种迭代找最近公共祖先的方法比较繁琐,因为对于需要寻找公共祖先的节点数量是未知的。

如果对于寻找节点的公共祖先问题不清楚,可以参考 二叉树的公共祖先 。

方法一:递归

接下来使用 递归 的方法来找出二叉树最深节点的最近公共祖先。

递归的遍历每个节点,返回当前子树的最大深度和最深叶节点的最近公共祖先节点(lca 节点),我们在递归的过程中:

  • 如果左子树更深,则最深的叶节点在左子树中,我们返回 {左子树的 lca 节点,左子树深度 +1 };
  • 如果右子树更深,则最深的叶节点在右子树中,我们返回 {右子树的 lca 节点,右子树深度 +1 };
  • 如果左右子树一样深,则左、右子树都有最深叶节点,我们返回 {当前节点,左子树深度 +1}。

最后,返回根节点的 lca 节点即可。

实现代码

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    pair<TreeNode*, int> dfs(TreeNode* node) {
            if (node == nullptr) {
                return {nullptr, 0};
            }

            auto [left_lca, left_heigh] = dfs(node->left);
            auto [right_lca, right_heigh] = dfs(node->right);

            if (left_heigh > right_heigh)
                return {left_lca, left_heigh + 1};

            if (right_heigh > left_heigh) 
                return {right_lca, right_heigh + 1};
            
            return {node, left_heigh + 1};
        };

    TreeNode* lcaDeepestLeaves(TreeNode* root) {
        return dfs(root).first;
    }
};

复杂度分析

时间复杂度: O ( n ) O(n) O(n),其中 n n n 是树的节点数量。

空间复杂度: O ( d ) O(d) O(d),其中 d d d 是树的深度。空间复杂度主要是递归的空间,最差情况为 O ( n ) O(n) O(n)


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 哦。

你可能感兴趣的:(LeetCode每日一题,递归,最近公共祖先,二叉树)