标签:左右子树 递归 dai else 否则 层序遍历 src 开始 lis
难度 medium
给定一个根为 root 的二叉树,每个节点的深度是 该节点到根的最短距离 。
如果一个节点在 整个树 的任意节点之间具有最大的深度,则该节点是 最深的 。
一个节点的 子树 是该节点加上它的所有后代的集合。
返回能满足 以该节点为根的子树中包含所有最深的节点 这一条件的具有最大深度的节点。
注意:本题与力扣 1123 重复:https://leetcode-cn.com/problems/lowest-common-ancestor-of-deepest-leaves/
示例 1:
输入:root = [3,5,1,6,2,0,8,null,null,7,4]
输出:[2,7,4]
解释:
我们返回值为 2 的节点,在图中用黄色标记。
在图中用蓝色标记的是树的最深的节点。
注意,节点 5、3 和 2 包含树中最深的节点,但节点 2 的子树最小,因此我们返回它。
示例 2:
输入:root = [1]
输出:[1]
解释:根节点是树中最深的节点。
示例 3:
输入:root = [0,1,3,null,2]
输出:[2]
解释:树中最深的节点为 2 ,有效子树为节点 2、1 和 0 的子树,但节点 2 的子树最小。
提示:
树中节点的数量介于 1 和 500 之间。
0 <= Node.val <= 500
每个节点的值都是独一无二的。
这道题我两个题解都是看的网上的资料,一开始给自己设置了20分钟,做不出来,后来就在网上看了答案,隔了一天之后再去做,才做好的。
解题思路1:这个题解非常朴素,就是一个这样的思想:用一个findHeight函数,负责找到某个节点的高度,然后从root节点开始遍历整棵树,如果root的左右子树的高度是一样的,那当前节点就是结果,因为左子树和右子树是没有公共节点的,如果他们高度一致,那一定是两边各有一个最深的节点,所以当前节点肯定就是结果了,否则符合条件的结果肯定是在高度较高的那棵子树中,因此我们比较左右子树的高度,然后对较高的那棵子树进行递归调用,从而找到目标。
代码 t100 s91 java
class Solution {
public TreeNode subtreeWithAllDeepest(TreeNode root) {
if(root==null) return null;
int leftHeight = findHeight(root.left);
int rightHeight = findHeight(root.right);
if(leftHeight==rightHeight) return root;
else if(leftHeight>rightHeight) return subtreeWithAllDeepest(root.left);
else return subtreeWithAllDeepest(root.right);
}
public int findHeight(TreeNode node){
if(node==null) return 0;
return Math.max(findHeight(node.left), findHeight(node.right)) + 1;
}
}
解题思路2:这个题解是在国外的网站上看到的,我其实一开始用的就是这个思路,但是在子节点和父节点之间建立映射关系这个方法我一直没有想到,所以也没写出来。说一下思路:用层序遍历的方法,遍历整棵树,最深的那一层肯定是最后遍历到的,我们用HashMap建立子节点和父节点之间的关系,用一个单向队列进行从左到右的遍历,用一个动态数组来储存每一层层序遍历得到的所有节点,遍历一层之后,如果q已经为空,那说明已经是最后一层,即将退出while(!q.isEmpty())的循环,此时直接用break结束语句,否则更新存储节点的动态数组,也就是这个动态数组中始终保存着最近遍历的那一层的所有节点。结束层序遍历之后,动态数组中就保存着最后一层的所有节点,我们再进入一个while循环,用一个HashSet保存动态数组中所有节点,因为HashSet具有去重的作用,当HashSet的大小为1时,说明已经找到了符合条件的节点,直接返回,否则就把节点数组i位置的节点设置为其父节点,这里用前面的HashMap来找到父节点,并重新回到上一步,新建一个HashSet,并往里面添加节点数组所有节点,直到HashSet的大小为1退出。
代码 t20 s16 java
class Solution {
public TreeNode subtreeWithAllDeepest(TreeNode root) {
Queue<TreeNode> q = new LinkedList<>();
HashMap<TreeNode, TreeNode> map = new HashMap<>();
ArrayList<TreeNode> nodes = new ArrayList<>();
q.add(root);
nodes.add(root);
while(!q.isEmpty()){
int sz = q.size();
ArrayList<TreeNode> tmp = new ArrayList<>();
for(int i=0; i<sz; i++){
TreeNode t = q.poll();
if(t.left!=null){
q.add(t.left);
tmp.add(t.left);
map.put(t.left, t);
}
if(t.right!=null){
q.add(t.right);
tmp.add(t.right);
map.put(t.right, t);
}
}
if(q.isEmpty()) break;
else nodes = tmp;
}
if(nodes.size()==1) return nodes.get(0);
while(true){
HashSet<TreeNode> set = new HashSet<>();
set.addAll(nodes);
if(set.size()==1) return nodes.get(0);
for(int i=0; i<nodes.size(); i++){
nodes.set(i, map.get(nodes.get(i)));
}
}
}
}
参考资料:
https://leetcode-cn.com/problems/smallest-subtree-with-all-the-deepest-nodes/solution/cu-su-yi-dong-zhi-jie-kan-dai-ma-he-zhu-z4exw/
https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/solution/
标签:左右子树 递归 dai else 否则 层序遍历 src 开始 lis
原文地址:https://www.cnblogs.com/zhengxch/p/14747288.html