二叉树中的最大路径和

给定一个非空二叉树,返回其最大路径和。

本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。

示例 1:

输入: [1,2,3]

       1

      / \

     2   3

输出: 6

示例 2:

输入: [-10,9,20,null,null,15,7]

   -10

   / \

  9  20

    /  \

   15   7

输出: 42

思路1 递归

根据题意,最大路径和可能出现在:

左子树中

右子树中

包含根节点与左右子树

我们的思路是递归从bottom向topreturn的过程中,记录左子树和右子树中路径更大的那个,并向父节点提供当前节点和子树组成的最大值。

递归设计:

返回值:(root.val) + max(left, right) 即此节点与左右子树最大值之和,较差的解直接被舍弃,不会再被用到。

需要注意的是,若计算结果tmp <= 0,意味着对根节点有负贡献,不会在任何情况选这条路(父节点中止),因此返回0。

递归终止条件:越过叶子节点,返回0;

记录最大值:当前节点最大值 = root.val + left + right。

最终返回所有路径中的全局最大值即可。

static private int maxSum;
public static int maxPathSum(TreeNode root) {
    maxSum  = Integer.MIN_VALUE;
    helper(root);
    return maxSum;
}
private static int helper(TreeNode node){
    if(node == null){
        return 0;
    }
    int leftSum = Math.max(helper(node.left),0);
    int rightSum = Math.max(helper(node.right),0);
    maxSum = Math.max(leftSum+rightSum+node.val,maxSum);
    return Math.max(leftSum,rightSum)+node.val;
}

这里有个问题就是为什么要

maxSum  = Integer.MIN_VALUE;

//这里为什么要进行初始化为Integer.MIN_VALUE  是因为有的点是负数,万一树全是负数呢

思路2

public static int maxPathSum(TreeNode root) {
    if(root == null){
        return 0;
    }
    int[] maxPath = new int[]{Integer.MIN_VALUE};
    dfs(root,maxPath);
    return maxPath[0];
}

/**
 * @Author liuhaidong
 * @Description 以root为顶点的直上直下的path中path sum 最大的一条值
 * @param
 * @Date 15:36 2019/10/8 0008
 */
private static int dfs(TreeNode root, int[] maxPath) {

    int left = root.left != null ? Math.max(dfs(root.left,maxPath),0): 0;
    int right = root.right != null ? Math.max(dfs(root.right,maxPath),0): 0;
    //并且以上两个还满足当前为叶子节点的时候再往下传了
    int cur = root.val + left + right;
    maxPath[0] = Math.max(maxPath[0],cur);
    return root.val + Math.max(left,right);
}

这里有个问题就是为什么传进来的是一个数组,

因为如果传进来的是一个数的话会被改变值,只有设置成全局变量或者是数组的话就不会改变。

向方法中传递数组

在java中,所有对象都是通过引用进行操作的。而数组也是一种对象,当把数组作为参数传递给方法时,传递的实际上就是数组对象的引用。在方法中对数组的所有操作,都会映射到原数组中。而所谓的"引用",就是java对象在堆内存的地址赋给了多个"栈内存"的变量。

主函数

public static void main(String[] args) {
    TreeNode root = new TreeNode(5);
    TreeNode node1 = new TreeNode(4);
    TreeNode node2 = new TreeNode(8);
    TreeNode node3 = new TreeNode(11);
    TreeNode node4 = new TreeNode(7);
    TreeNode node5 = new TreeNode(2);
    TreeNode node6 = new TreeNode(13);
    TreeNode node7 = new TreeNode(4);
    TreeNode node8 = new TreeNode(1);
    root.left=node1;
    root.right=node2;
    node1.left=node3;
    node3.left=node4;
    node3.right=node5;
    node2.left=node6;
    node2.right=node7;
    node7.right=node8;
    System.out.println(maxPathSum(root));
}