二叉树中的最大路径和
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 44 ms, 内存: 21.0 MB
/*
* 思路:
* 我们需要找到二叉树中的最大路径和。路径可以从任何节点开始,到任何节点结束,且每个节点至多出现在路径中一次。
* 使用递归的方法来解决这个问题。我们定义一个辅助函数 maxGain(node),它计算从节点 node 出发的最大贡献值。
* 对于每个节点,考虑两种情况:
* 1. 当前节点独立成一个路径的起点,那么最大路径和是 node.val + maxGain(node.left) + maxGain(node.right)
* 2. 当前节点作为上一级路径的一部分,那么最大贡献值是 node.val + max(maxGain(node.left), maxGain(node.right))
*
* 在递归过程中,我们会不断更新全局的最大路径和。
*
* 这里使用Java Stream API来简化代码
*/
import java.util.stream.Stream;
class Solution {
private int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxGain(root);
return maxSum;
}
private int maxGain(TreeNode node) {
if (node == null) return 0;
// 递归计算左右子节点的最大贡献值
int leftGain = Math.max(maxGain(node.left), 0);
int rightGain = Math.max(maxGain(node.right), 0);
// 当前节点的最大路径和
int priceNewPath = node.val + leftGain + rightGain;
// 更新全局最大路径和
maxSum = Math.max(maxSum, priceNewPath);
// 返回当前节点的最大贡献值
return node.val + Stream.of(leftGain, rightGain).mapToInt(Integer::intValue).max().orElse(0);
}
}
解释
方法:
这个方法利用深度优先搜索(DFS)遍历二叉树的每个节点,同时计算以每个节点为顶点的最大路径和。对于每个节点,考虑两种情况:1.路径包括该节点及其左右子树;2.路径不包括子树,只有该节点自己。具体算法中,首先计算左右子树提供的最大贡献值,如果子树的贡献值为负,则认为不包括该子树的贡献。然后,更新全局的最大路径和,包括当前节点值以及左右子树的最大贡献。此外,函数返回到父节点的最大单边路径和,以便父节点计算其最大路径和时使用。这种方法确保我们计算了所有可能的路径,并在遍历过程中保存了最大值。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在更新全局最大路径和时考虑了左右子树的贡献值与当前节点值之和,而返回到父节点的路径和时只考虑了其中的最大单边路径和加当前节点值?
▷🦆
如果节点的值为负数,会如何影响算法计算左右子树的贡献值和最终的最大路径和?
▷🦆
在函数中使用了非局部变量`ans`进行全局最大路径和的更新,这种方式与传递参数相比有什么优缺点?
▷