要点在于 【分解】。
如果我们换个问法,怎么求出二叉树中根节点出发的最长路径和?用递归可以很快的写出计算逻辑
// 定义:计算从根节点 root 为起点的最大单边路径和
int oneSideMax(TreeNode root) {
if (root == null) {
return 0;
}
int leftMaxSum = Math.max(0, oneSideMax(root.left));
int rightMaxSum = Math.max(0, oneSideMax(root.right));
// 实现函数定义,左右子树的最大单边路径和加上根节点的值
// 就是从根节点 root 为起点的最大单边路径和
return Math.max(leftMaxSum, rightMaxSum) + root.val;
}
然后题目中,不限定是否以 Root 节点为起点。对于任意的某个节点来说,其最大的路径和,就是【左最长路径】+【右最长路径和】+ 【当前节点值】。
所以定义一个全局变量 res,然后在每次求二叉树根节点的值的时候,找出最大值。
// 后序遍历位置,顺便更新最大路径和
int pathMaxSum = leftMaxSum + rightMaxSum + root.val;
res = Math.max(res, pathMaxSum);
完整的逻辑如下
class Solution {
int res = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
if (root == null) {
return 0;
}
// 计算单边路径和时顺便计算最大路径和
oneSideMax(root);
return res;
}
// 定义:计算从根节点 root 为起点的最大单边路径和
int oneSideMax(TreeNode root) {
if (root == null) {
return 0;
}
int leftMaxSum = Math.max(0, oneSideMax(root.left));
int rightMaxSum = Math.max(0, oneSideMax(root.right));
// 后序遍历位置,顺便更新最大路径和
int pathMaxSum = root.val + leftMaxSum + rightMaxSum;
res = Math.max(res, pathMaxSum);
// 实现函数定义,左右子树的最大单边路径和加上根节点的值
// 就是从根节点 root 为起点的最大单边路径和
return Math.max(leftMaxSum, rightMaxSum) + root.val;
}
}