[LeetCode] Smallest Subtree with all the Deepest Nodes 包含最深结点的最小子树
Given a binary tree rooted at `root`, the *depth* of each node is the shortest distance to the root.
A node is deepest if it has the largest depth possible among any node in the entire tree.
The subtree of a node is that node, plus the set of all descendants of that node.
Return the node with the largest depth such that it contains all the deepest nodes in its subtree.
Example 1:
Input: [3,5,1,6,2,0,8,null,null,7,4]
Output: [2,7,4]
Explanation:

We return the node with value 2, colored in yellow in the diagram.
The nodes colored in blue are the deepest nodes of the tree.
The input "[3, 5, 1, 6, 2, 0, 8, null, null, 7, 4]" is a serialization of the given tree.
The output "[2, 7, 4]" is a serialization of the subtree rooted at the node with value 2.
Both the input and output have TreeNode type.
Note:
- The number of nodes in the tree will be between 1 and 500.
- The values of each node are unique.
这道题给了我们一棵二叉树,让我们找包含所有最深结点的最小子树,就是返回这棵最小子树的根结点。题目中给了一个例子,因为有图,所以可以很直接的看出来最深的结点是7和4,那么包含这两个结点的最小子树的根结点是2,返回即可。其实最深的结点不一定只有两个,可能有很多个,比如对于一棵完全二叉树,即把例子图中的结点7和4去掉后,此时最深的结点就有四个,分别是6,2,0,8,都包含这些结点的子树就是原树本身了,要返回根结点。
通过上述分析,可以发现,子树的最大深度很重要,对于一棵完全二叉树来说,根结点的左右子树的最大深度一定是相同的,此时直接返回根结点即可。若左右子树的最大深度不同,则最深结点一定位于深度大的子树中,可以对其调用递归函数。所以只需要写一个计算最大深度的递归函数,来计算左右子树的最大深度差,再根据这个差值来决定对谁调用当前的递归函数,两个递归函数相互缠绕,画面美极了,参见代码如下:
解法一:
class Solution {
public:
TreeNode* subtreeWithAllDeepest(TreeNode* root) {
int diff = depth(root->left) - depth(root->right);
return (diff == 0) ? root : subtreeWithAllDeepest(diff > 0 ? root->left : root->right);
}
int depth(TreeNode* node) {
return !node ? 0 : max(depth(node->left), depth(node->right)) + 1;
}
};
上面的解法其实并不高效,因为对于每个结点,都要统计其左右子树的最大深度,有大量的重复计算存在,我们来尝试提高时间复杂度,就不可避免的要牺牲一些空间。递归函数需要返回一个 pair,由每个结点的最大深度,以及包含最深结点的最小子树组成。所以在原函数中,对根结点调用递归函数,并取返回的 pair 中的第二项。
在递归函数中,首先判断结点是否存在,为空的话直接返回一个 {0, NULL} 对儿。否则分别对左右子结点调用递归函数,将各自的返回的 pair 存入 left 和 right 中,然后先分别在 left 和 right 中取出左右子树的最大深度 d1 和 d2,之后就要建立返回值的 pair,第一项为当前结点的最大深度,由左右子树中的最大深度加1组成,而包含最深结点的最小子树由 d1 和 d2 值的大小决定,若 d1>d2,则为 left.second,否则为 right.second,这样我们就把原本的两个递归,揉合到了一个递归函数中,大大提高了运行效率,参见代码如下:
解法二:
class Solution {
public:
TreeNode* subtreeWithAllDeepest(TreeNode* root) {
return helper(root).second;
}
pair<int, TreeNode*> helper(TreeNode* node) {
if (!node) return {0, NULL};
auto left = helper(node->left), right = helper(node->right);
int d1 = left.first, d2 = right.first;
return {max(d1, d2) + 1, (d1 == d2) ? node : (d1 > d2 ? left.second : right.second)};
}
};
Github 同步地址:
https://github.com/grandyang/leetcode/issues/865
参考资料:
https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/
https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/discuss/146808/One-pass
[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
[LeetCode] Smallest Subtree with all the Deepest Nodes 包含最深结点的最小子树的更多相关文章
- 865. Smallest Subtree with all the Deepest Nodes 有最深节点的最小子树
[抄题]: Given a binary tree rooted at root, the depth of each node is the shortest distance to the roo ...
- leetcode_865. Smallest Subtree with all the Deepest Nodes
https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/ 给定一颗二叉树,输出包含所有最深叶子结点的最小子树 ...
- LeetCode 865. Smallest Subtree with all the Deepest Nodes
原题链接在这里:https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/ 题目: Given a binar ...
- 【LeetCode】865. Smallest Subtree with all the Deepest Nodes 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- [Swift]LeetCode865. 具有所有最深结点的最小子树 | Smallest Subtree with all the Deepest Nodes
Given a binary tree rooted at root, the depth of each node is the shortest distance to the root. A n ...
- [LeetCode] 1123. Lowest Common Ancestor of Deepest Leaves 最深叶结点的最小公共父节点
Given a rooted binary tree, return the lowest common ancestor of its deepest leaves. Recall that: Th ...
- FB面经 Prepare: LCA of Deepest Nodes in Binary Tree
给一个 二叉树 , 求最深节点的最小公共父节点 . retrun . 先用 recursive , 很快写出来了, 要求用 iterative . 时间不够了... Recursion: 返回的时候返 ...
- Leetcode之深度优先搜索(DFS)专题-1123. 最深叶节点的最近公共祖先(Lowest Common Ancestor of Deepest Leaves)
Leetcode之深度优先搜索(DFS)专题-1123. 最深叶节点的最近公共祖先(Lowest Common Ancestor of Deepest Leaves) 深度优先搜索的解题详细介绍,点击 ...
- LeetCode 1123. Lowest Common Ancestor of Deepest Leaves
原题链接在这里:https://leetcode.com/problems/lowest-common-ancestor-of-deepest-leaves/ 题目: Given a rooted b ...
随机推荐
- Docker-----仓库
安装registry 安装并启动docker yum -y install docker systemctl enable docker systemctl start docker 下载regist ...
- PMI-ACP练习题知识积累-打印版
敏捷铁三角的参数:价值,质量,约束.传统的铁三角包括的参数是范围,进度和成本 敏捷计划的三个主要层级为:发布计划,迭代计划,每日计划 敏捷开发模型的特征包括 开发由多个迭代组成. 敏捷拥抱不确定性,而 ...
- 【Python】Flask中@wraps的使用
先说总结,白话来讲,@wraps相当于是装饰器的装饰器. python内置的方法使用解释,看起很复杂的样子┓( ´∀` )┏ def wraps(wrapped, assigned = WRAPPER ...
- linux常用基础命令(一)
Rz命令 rz命令本地上传文件到服务器: rz在弹出的框中选择文件,上传文件 sz命令 sz命令发送文件到本地: Sz文件名 例:将文件file1 Sz file1 Tomcat启动/关闭命令 比如t ...
- 配置SSL证书
在阿里云买了SSL证书,但是访问的时候提示如下图: 这个就郁闷了,按照这个方式导入了证书,但还是不行,后来得到同事的帮助,使用这个工具 然后重启下服务器就可以了.
- js数据结构与算法——集合
<script> function Set(){ var items = {};//使用对象表示集合,因为js对象不允许一个键指向两个不同的值,保证集合里面的匀速唯一性 this.add ...
- 初学python之路-day11
一.函数的参数:实参与形参 # 参数介绍: # 函数为什么要有参数:因为内部的函数体需要外部的数据 # 怎么定义函数的参数:在定义函数阶段,函数名后面()中来定义函数的参数 # 怎么使用函数的参数:在 ...
- 程序员不能忍996了!全民 fuck ,GitHub来说话
前两天有个Github超级火的一个项目,在一小时之内星标上千. https://github.com/997icu/996.ICU 截至目前 这个项目start数量超过63K.Issues5000 ...
- MySQL之排序、分组(五)
一.排序 格式:select * from 表 order by 字段 asc|desc 1.查询所有的商品进行排序(升序asc.降序desc) mysql> select * from pro ...
- UGUI中粒子特效与UI的遮挡问题
问题背景: 在做主线任务时发现完成任务后的特效显示穿透上面的UI层,不美观,策划不乐意了,抓紧解决下 解决思路: 首先讲下影响渲染顺序的因素: 能够影响渲染顺序的因素有:1.Camera Depth ...