124. 二叉树中的最大路径和

195 阅读2分钟

image.png

写法1

class Solution {
    int max = Integer.MIN_VALUE;//不能设置为0,比如输入为[-3]
    public int maxPathSum(TreeNode root) {
        dfs(root);
        return max;
    }
    //dfs(node)表示包含node的最大路径和,是一条线,没有分支,所以最后return一边。
    public int dfs(TreeNode node) {
        if (node == null) {
            return 0;
        }
        int leftSum = Math.max(0, dfs(node.left));
        int rightSum = Math.max(0, dfs(node.right));
        int curSum = leftSum + rightSum + node.val; // 当前节点及其以下的最大路径和
        max = Math.max(curSum, max);
        return Math.max(leftSum, rightSum) + node.val;//只能选一边
    }
}
class Solution {
    int max = Integer.MIN_VALUE;//不能设置为0,比如输入为[-3]
    public int maxPathSum(TreeNode root) {
        if (root == null) {
            return 0;
        }
        dfs(root);
        return max;
    }
    //dfs(node)表示包含node的最大路径和,是一条线,没有分支,所以最后return一边。
    public int dfs(TreeNode node) {
        if (node == null) {
            return 0;
        }
        // 递归计算左右子节点的最大贡献值
        // 只有在最大贡献值大于 0 时,才会选取对应子节点,leftSum/rightSum = 0,表明没有选择这个子节点
        // 相当于舍弃路径和小于零的子节点分支
        //为什么不要负的? 因为宁可要自己
        int leftSum = Math.max(0, dfs(node.left));
        int rightSum = Math.max(0, dfs(node.right));
        //当前节点的最大路径和:取决于1.左子树贡献 2.右子树贡献 3.本节点贡献
        max = Math.max(leftSum + rightSum + node.val, max);
        //返回以当前节点的贡献,为root的子树的左侧或右侧sum(取决于哪测sum更大)
        //这样也保证了返回的是一条线,不分叉
        return Math.max(leftSum, rightSum) + node.val;//只能选一边
    }
}

写法2

class Solution {
    int max = Integer.MIN_VALUE;//不能设置为0,比如输入为[-3]
    public int maxPathSum(TreeNode root) {
        if (root == null) {
            return 0;
        }
        dfs(root);
        return max;
    }
    public int dfs(TreeNode node) {
        if (node == null) {
            return 0;
        }
        // 递归计算左右子节点的最大贡献值
        // 只有在最大贡献值大于 0 时,才会选取对应子节点,leftSum/rightSum = 0,表明没有选择这个子节点
        int leftSum = dfs(node.left);
        int rightSum = dfs(node.right);
        //当前节点的最大路径和:取决于1.左子树贡献 2.右子树贡献 3.本节点贡献
        max = Math.max(leftSum + rightSum + node.val, max);
        //返回以当前节点的贡献,为root的子树的左侧或右侧sum(取决于哪测sum更大)
        //这样也保证了返回的是一条线,不分叉
        return Math.max(0, Math.max(leftSum, rightSum) + node.val);
    }
}