【发布时间】:2021-03-17 17:25:30
【问题描述】:
GeeksforGeeks 网站针对二叉树的最大路径和问题提出了a solution。问题如下:
给定一棵二叉树,求最大路径和。路径可能开始并且 在树中的任何节点处结束。
解决方案的核心如下:
int findMaxUtil(Node node, Res res)
{
if (node == null)
return 0;
// l and r store maximum path sum going through left and
// right child of root respectively
int l = findMaxUtil(node.left, res);
int r = findMaxUtil(node.right, res);
// Max path for parent call of root. This path must
// include at-most one child of root
int max_single = Math.max(Math.max(l, r) + node.data,
node.data);
// Max Top represents the sum when the Node under
// consideration is the root of the maxsum path and no
// ancestors of root are there in max sum path
int max_top = Math.max(max_single, l + r + node.data);
// Store the Maximum Result.
res.val = Math.max(res.val, max_top);
return max_single;
}
int findMaxSum() {
return findMaxSum(root);
}
// Returns maximum path sum in tree with given root
int findMaxSum(Node node) {
// Initialize result
// int res2 = Integer.MIN_VALUE;
Res res = new Res();
res.val = Integer.MIN_VALUE;
// Compute and return result
findMaxUtil(node, res);
return res.val;
}
Res 有如下定义:
class Res {
public int val;
}
我对这些代码行背后的推理感到困惑:
int max_single = Math.max(Math.max(l, r) + node.data, node.data);
int max_top = Math.max(max_single, l + r + node.data);
res.val = Math.max(res.val, max_top);
return max_single;
我相信上面的代码遵循这个逻辑,但我不明白为什么这个逻辑是正确或有效的:
对于每个节点,最大路径可以通过四种方式 节点:
- 仅节点
- 通过左孩子 + 节点的最大路径
- 通过右子节点 + 节点的最大路径
- 通过左孩子的最大路径 + 节点 + 通过右孩子的最大路径
特别是,当我们变量res.val包含我们感兴趣的答案时,我不明白为什么在函数findMaxUtil中返回max_single。以下原因在网站上给出但我不明白了:
需要注意的重要一点是,每个子树的根都需要返回 最大路径总和,使得最多包含一个根的孩子。
有人可以解释一下解决方案的这一步吗?
【问题讨论】:
-
使用这种方法是因为
findMaxUtil是一个递归函数。这里,res用于跟踪调用findMaxUtil时将传递的整体最大值,随后将用于在传递树节点期间与路径总和进行比较。其他方法是在语言支持时将res作为全局变量。 -
@akuzminykh 给定的解决方案通过Leetcode tests
-
逻辑表明最大路径不必总是从根开始。最大路径总和可能是它的子树之一。
-
@a_sid,每经过一个节点,有5个新的max-sum-path候选,即
left+current node、right+current node、current node、left+right+current node和max-sum -路径或res。比较这 5 个值将产生新的 max-sum-path/res。如果我们观察,这里考虑current node,因为一个节点可以有负值,所以current node数据仍有可能大于current node+left或current node+right。 -
@a_sid 例如,如果您遵循 Java 命名约定,您的 max_single 将是 maxSingle。
标签: java algorithm binary-tree