题目描述
给定一个二叉树,请计算节点值之和最大的路径的节点值之和是多少。
这个路径的开始节点和结束节点可以是二叉树中的任意节点。
例如:给出以下的二叉树,返回的结果为6
示例1
输入:{-2,1}
返回值:1
题目分析
题目描述的路径可以从任意节点开始到任意节点结束,与之前必须要从根节点到叶子结点的路径不同,如下图,最大和的路径为2 -> 1 -> 3 -> 1。
遍历树的结点可以使用dfs,后序遍历。
解题思路
方法:后序遍历树结点,统计可以获得的最大路径和
思路过程:
1.从叶子结点开始遍历,计算从任意节点开始的路径和值 int cur = node.val;
2.对于结点的路径来说,可以往左子节点和右子节点延伸,left表示左子节点最大值, right表示右子节点最大值;
3.最后返回的值需要选择在此结点的值(加上左右最大值)和此点往左或右的路径最大值中选择更大的值: Math.max(cur, Math.max(root.val,Math.max(left, right) + root.val))。
代码实现
Java实现
public int max = Integer.MIN_VALUE;
public int maxPathSum (TreeNode root) {
// write code here
backtrace(root);
return max;
}
public int backtrace(TreeNode root){
if(root == null) return 0;
// 后序遍历,最后计算和,避免根节点值重复计算
// 计算左、右子结点最大路径和
int left = backtrace(root.left);
int right = backtrace(root.right);
int cur = root.val;
if(left > 0){
// 获取左子节点值
cur += left;
}
if(right > 0){
// 获取右子节点值
cur += right;
}
// 统计出现的最大路径和
max = Math.max(max, cur);
// 返回当前最大路径和,不能直接返回cur,因为cur包含了两条路径,而返回只能一条路径
return Math.max(root.val, Math.max(left, right) + root.val);
}时间复杂度:O(n),n为树中所有的结点数量,遍历整个树消耗时间n;
空间复杂度:O(n),递归栈最大的深度为n;
C++实现
int maxPathSum(TreeNode *root) {
// write code here
dfs(root);
return maxSum;
}
int dfs(TreeNode *root) {
if (!root) return 0;
// 获得左右子节点的最大路径和
int left = dfs(root->left);
int right = dfs(root->right);
int current = root->val;
// 当左右子节点值大于0时,当前值加上 左右子节点的值
if (left > 0) current += left;
if (right > 0) current += right;
// 记录出现的最大值
maxSum = max(maxSum, current);
// 返回当前最大路径和,不能直接返回cur,因为cur包含了两条路径,而返回只能一条路径
return max(root->val, max(left, right) + root->val);
}
private:
int maxSum = INT_MIN;复杂度与Java实现相同。

京公网安备 11010502036488号