题目
给定一个根为 root 的二叉树,每个节点的深度是 该节点到根的最短距离 。
如果一个节点在 整个树 的任意节点之间具有最大的深度,则该节点是 最深的.
一个节点的 子树 是该节点加上它的所有后代的集合。
返回能满足 以该节点为根的子树中包含所有最深的节点 这一条件的具有最大深度的节点。
输入:root = [3,5,1,6,2,0,8,null,null,7,4]
输出:[2,7,4]
解释:
我们返回值为 2 的节点,在图中用黄色标记。
在图中用蓝色标记的是树的最深的节点。
注意,节点 5、3 和 2 包含树中最深的节点,但节点 2 的子树最小,因此我们返回它。
读了半天也没有搞清楚,自己写了一下,果不其然出错了。
分析
返回 “以该节点为根的子树中包含所有最深的节点 这一条件的具有最大深度的节点”,
也就是返回的节点得是一个有根的树——如果我们假定 A 是一组节点 S 的 最近公共祖先,S 中的每个节点都在以 A 为根节点的子树中,且 A 的深度达到此条件下可能的最大值。
抓取关键点
最深 、子树
什么是深度——深度是从根节点往下
最深——某个节点到根的距离最大
思路
- 从树根开始,获得树根的左右子树的最大深度,比较left和right的大小,看哪一边深度最深;
- 如果深度不相同,则去深度大的子树继续判断;
- 直到左右子树的深度相等,返回root,即为最深叶节点的最近公共祖先,也是含有最深节点的子树
public TreeNode lcaDeepestLeaves(TreeNode root) {
if (root == null) {
return root;
}
int left = dfs(root.left);
int right = dfs(root.right);
if (left == right) {
return root;
} else if (left > right) {
return lcaDeepestLeaves(root.left);
} else {
return lcaDeepestLeaves(root.right);
}
}
public int dfs(TreeNode root) {
if (root == null) {
return 0;
}
int left = dfs(root.left);
int right = dfs(root.right);
return Math.max(left, right) + 1;
}
重点在:要想到找左右子树的深度,然后去递归深度大的子树,直到找到左右子树深度相等的root。
end.