求最深的叶子节点的最近公共祖先
我的解法很懒,就是先找到最深的节点集合,然后一个个地merge
int depth = -1;
Map<TreeNode, TreeNode> map = new HashMap<>();
Map<TreeNode, Integer> deMap = new HashMap<>();
List<TreeNode> list = new ArrayList<>();
public TreeNode subtreeWithAllDeepest(TreeNode root) {
dfs(root, null, 1);
dfs(root, 1);
TreeNode res = list.get(0);
for (int i = 1; i< list.size(); i++) {
res = merge(list.get(i), res);
}
return res;
}
private TreeNode merge(TreeNode treeNode, TreeNode res) {
while (deMap.get(treeNode) > deMap.get(res)) {
treeNode = map.get(treeNode);
}
while (deMap.get(res) > deMap.get(treeNode)) {
res = map.get(res);
}
while(treeNode.val != res.val) {
treeNode = map.get(treeNode);
res = map.get(res);
}
return res;
}
private void dfs(TreeNode root, int d) {
if (root == null) return;
if (d == depth) {
list.add(root);
}
dfs(root.left, d + 1);
dfs(root.right, d + 1);
}
private void dfs(TreeNode root, TreeNode parent, int d) {
if (root == null) return;
map.put(root, parent);
deMap.put(root, d);
depth = Math.max(depth, d);
dfs(root.left, root, d + 1);
dfs(root.right, root, d + 1);
}
看了评论区,大神的解法
大致思路是,最深的叶子节点深度为0,它们的父节点深度1,爷爷节点为2。。。
如果左右子树深度相同,那么最深的叶子节点两边都有,如果不同,那么最深的叶子节点在比较大的那边。
https://leetcode.com/problems/smallest-subtree-with-all-the-deepest-nodes/discuss/146808/One-pass
下面的回复中比较详细的解析和比较清晰的注释和改造后的代码
public TreeNode subtreeWithAllDeepest(TreeNode root) {
return deep(root).getValue();
}
public Pair<Integer, TreeNode> deep(TreeNode root) {
if (root == null) return new Pair(0, null);
Pair<Integer, TreeNode> l = deep(root.left), r = deep(root.right);
int d1 = l.getKey(), d2 = r.getKey();
return new Pair(Math.max(d1, d2) + 1, d1 == d2 ? root : d1 > d2 ? l.getValue() : r.getValue());
}