[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 ...
随机推荐
- hihocoder 1176
hihocoder 1176 题意:N,M.分别表示岛屿数量和木桥数量,一笔画 分析:欧拉路问题(给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路) 欧拉路的条件 一个无向 ...
- 【easy】Number of Segments in a String 字符串中的分段数量
以空格为分隔符,判断一个string可以被分成几部分. 注意几种情况:(1)全都是空格 (2)空字符串(3)结尾有空格 思路: 只要统计出单词的数量即可.那么我们的做法是遍历字符串,遇到空格直接跳过, ...
- debug 2
Red Hat Developer Toolsetdelivers the latest stable versions of essential GCC C, C++, Fortran, and s ...
- js-面试题整理
var Foo = function(){ getName = function(){alert(1)}; return this; } Foo.getName = function(){alert( ...
- java sigar获取本地信息以及org.hyperic.sigar.SigarException: The device is not ready报错解决
window下,使用java sigar 获取磁盘使用率,cpu使用率以及内存使用情况等信息时. 一:首先需要下载jar包和相关文件 sigar-1.6.4.zip 如果想了解更多可以去 sigar官 ...
- Mysql配置优化,库表设计
Mysql 服务器参数类型: 基于参数的作用域: 全局参数:set global autocommit = ON/OFF; 会话参数(会话参数不单独设置则会采用全局参数):set session au ...
- 从Learning to Segment Every Thing说起
原文地址:https://arxiv.org/pdf/1711.10370.pdf 这是何恺明老师发表于CVPR2018的一篇优秀paper. 先简单回顾一下语义分割领域之前的工作 那么什么是语义分割 ...
- LoadRunner脚本准备
脚本录制1.启动LoadRunner2.打开VuGen在LoadRunner Launcher窗格中,单击创建/编辑脚本3.创建一个空白Web脚本在“新建虚拟用户”对话框里选择新建脚本的协议一般选择W ...
- zabbix_agentd客户端安装与配置(windows操作系统)
zabbix_agentd客户端安装与配置(windows操作系统) ********** 客户端操作 ********** 标注:监控zabbix_agentd客户端安装对象是win s ...
- Spring 源码学习系列
前言 Spring框架之于 JavaEE 程序员来说,犹如锄头之于农民.Java 程序员每天都要使用Spring框架,Spring框架也确实是个可手的工具. 最初使用Spring的时候,我们需要配置m ...