题目:
给定二叉树的根节点 root,找出存在于 不同 节点 A 和 B 之间的最大值 V,其中 V = |A.val - B.val|,且 A 是 B 的祖先。
(如果 A 的任何子节点之一为 B,或者 A 的任何子节点是 B 的祖先,那么我们认为 A 是 B 的祖先)
思路:
我真神了, 竟然想到了 -- 只需计算当前节点与最大值和最小的的差的绝对值
不过我还是没过, 因为我搞了个全局的max和min
这样就会导致遍历到右子树时, 会与左子树的节点值进行计算
这是不应该的
于是,应该用参数传递max和min进去
这里有一个疑惑的点, 就是传参会复制一份值,左子树改变了,右子树不会收到影响
让我们看看你认可的那个“前序遍历”代码是怎么跑的:
javascript
编辑
function dfs(node, maxVal, minVal) {
// ...
let newMax = Math.max(maxVal, node.val);
let newMin = Math.min(minVal, node.val);
// 关键点在这里 👇
dfs(node.left, newMax, newMin); // 调用 1
dfs(node.right, newMax, newMin); // 调用 2
}
假设根节点是 8,左孩子是 3,右孩子是 10。
-
根节点 (8) :
- 算出
newMax = 8,newMin = 8。 - 执行 调用 1:把数字 8 和 8 传给左孩子。
- 执行 调用 2:把数字 8 和 8 传给右孩子。
- 算出
-
左孩子 (3) :
- 它收到的参数是 8, 8。
- 它算出
newMax = 8,newMin = 3。 - 它继续往下传...
- 注意:哪怕左孩子把
newMin改成了 3,甚至改成了 100,这跟右孩子有什么关系呢?
-
右孩子 (10) :
- 它收到的参数依然是根节点给的 8, 8。它根本不知道左孩子那边发生了什么。
代码:
var maxAncestorDiff = function (root) {
//每个节点只需要和自己的子树中的最大值和最小值进行计算
let res = 0;
function dfs(root, max, min) {
if (!root) return;
//计算
let sum = Math.max(res, Math.abs(root.val - min), Math.abs(root.val - max));
res = sum > res ? sum : res;
//添加上当前节点,看看最大值和最小值变化没
let newMax = Math.max(max, root.val);
let newMin = Math.min(min, root.val);
dfs(root.left, newMax, newMin);
dfs(root.right, newMax, newMin);
}
dfs(root, root.val, root.val);
return res;
};