题目描述
给定二叉树的根节点 root,找出存在于 不同 节点 A 和 B 之间的最大值 V,其中 V = |A.val - B.val|,且 A 是 B 的祖先。
(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)
示例 1
输出:7
结点 1 和 8 之间的差值最大。
题解
”暴力“实现
以深度优先搜索为框架,维持一个有续集来记录路径上的元素。
代码
class Solution {
int ans = 0;
int min;
int max;
TreeSet<Integer> set = new TreeSet<>(Comparator.comparingInt(a -> a));
public int maxAncestorDiff(TreeNode root) {
min = root.val;
max = root.val;
dfs(root);
return ans;
}
private void dfs(TreeNode root) {
if (root == null) {
return;
}
int val = root.val;
set.add(val);
// update min, max, and ans
min = Math.min(root.val, min);
max = Math.max(root.val, max);
ans = Math.max(ans, max - min);
// recursive call
dfs(root.left);
dfs(root.right);
// rollback state
set.remove(val);
if (set.isEmpty()) {
return;
}
if (val == max) {
max = set.last();
}
if (val == min) {
min = set.first();
}
}
}
复杂度分析
这样的解法的时间复杂度为 ,空间复杂度为 , 为数的最大深度。
优化解法
其实没有必要用一个集来记录当前路径上的元素,直接将这个信息保存在递归函数的参数列表中即可,只不过保存的信息不再是全部的元素,而是当前的最大值和最小值。
代码
public class Solution {
int ans = 0;
public int maxAncestorDiff(TreeNode root) {
dfs(root, root.val, root.val);
return ans;
}
private void dfs(TreeNode root, int min, int max) {
if (root == null) {
return;
}
int val = root.val;
ans = Math.max(ans, Math.max(Math.abs(val - min), Math.abs(val - max)));
min = Math.min(min, val);
max = Math.max(max, val);
dfs(root.left, min, max);
dfs(root.right, min, max);
}
}
复杂度分析
这样的解法的时间复杂度为 。