文章目录
- Tag
- 题目来源
- 题目解读
- 解题思路
- 方法一:递归
- 写在最后
Tag
【递归】【最近公共祖先】【二叉树】
题目来源
1123. 最深叶节点的最近公共祖先,865. 具有所有最深节点的最小子树 此二题系重复的题目。
题目解读
题目意思很明确,找出二叉树最深节点的最近公共祖先。二叉树中每个节点的值都是独一无二的。
解题思路
寻找节点的最近公共祖先的一个朴素思想是:记录每一个节点的父节点,然后通过迭代的方式找到节点的最近公共祖先。在本题中需要先找到深度最深的那些节点,这些节点可能是两个节点也能是多个节点,可以预见的是这种迭代找最近公共祖先的方法比较繁琐,因为对于需要寻找公共祖先的节点数量是未知的。
如果对于寻找节点的公共祖先问题不清楚,可以参考 二叉树的公共祖先 。
方法一:递归
接下来使用 递归 的方法来找出二叉树最深节点的最近公共祖先。
递归的遍历每个节点,返回当前子树的最大深度和最深叶节点的最近公共祖先节点(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)。
写在最后
如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。
如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。
最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。