LeetCode——124. Binary Tree Maximum Path Sum

问题描述:

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.

For example:
Given the below binary tree,
       1
      / \
     2   3
Return 6.

  这道题大致的意思就是在一棵二叉树中寻找最大路径(下文称为最长路径),但是这个最长路径的起点和终点并不限制,只要是在一条路径上就行。
  虽然是道hard的题,但是实际上逻辑还是比较清晰的。其实很明显,这道题不可能直接去处理细节,真的去找那条最长的路径,(也可以将它转换为图,然后用图的路径算法,但是太麻烦了)而是要从全局来看:求一棵树中的最长路径,无非就是求左子树的最长路径(如果左子树路径值大于0的话)加上右子树的最长路径(如果右子树路径值大于0的话)。因此我们可以通过递归去求左子树的最长路径和右子树的最长路径,然后根据两个路径是否大于0来取这整一棵数的最长路径,问题迎刃而解。所以要学会将小的放到全局来看,不要直接去处理不好操作的细节,而通过放大到全局来处理。
  在递归处理时,具体的递归处理逻辑如下:
  ①首先获取左子树的最长路径和右子树的最长路径,并判断它们是否能够更新总的最长路径。(因为有可能当前节点的值为一个很大的负数,使得本身大于总的最长路径的子树路径变小)
  ②计算以当前节点为根节点的这棵树的最长路径(即如果左子树或者右子树的最长路径值为非负数,就加进来,再加上当前节点的值),然后判断这棵树能否更新总的最长路径值。
  ③处理完后,需要返回这棵树的最长路径值。因为对于上一层的节点来说,这棵树只能返回一个路径值,才能够与另一个路径进行拼接,所以我们从左子树路径值和右子树路径值中取一个最大的,加上当前点的值,就是所要返回的值。
  下面是具体代码:

    public int maxPath = Integer.MIN_VALUE;

    public int maxPathSum(TreeNode root) {
        if(root == null)
            return 0;
        int result = PathSum(root);
        if(result > maxPath)
            return result;
        return maxPath;
    }

    public int PathSum(TreeNode node) {
        //当遇到叶子结点时,直接返回该节点的值
        if(node.left == null && node.right == null)
            return node.val;
        int leftPathSum = Integer.MIN_VALUE;
        int rightPathSum = Integer.MIN_VALUE;
        int pathSum = node.val;
        //遍历左子树和右子树,去获取两边的最长路径
        if(node.left != null)
            leftPathSum = PathSum(node.left);
        if(node.right != null)
            rightPathSum = PathSum(node.right);
        //根据左子树的最长路径和右子树的最长路径来判断是否要更新最大值
        if(leftPathSum > maxPath)
            maxPath = leftPathSum;
        if(rightPathSum > maxPath)
            maxPath = rightPathSum;
        //然后将左子树路径和右子树路径进行转换,正数不变,负数变为0
        //因为后面要进行相加求和的操作,很显然,路径值为负数的,我们不会加进去
        //所以为了方便操作,直接将负数的路径值置0
        leftPathSum = Math.max(0, leftPathSum);
        rightPathSum = Math.max(0, rightPathSum);
        //计算以当前节点为根节点的树中的最长路径,并更新最长路径
        pathSum += leftPathSum + rightPathSum;
        if(pathSum > maxPath)
            maxPath = pathSum;
        //因为对于上一层节点来说,在这一棵树中实际上只是取一个路径
        //所以我们要么取右子树加当前节点为最长路径,要么取左子树加当前节点为最长路径,返回给上一层节点
        return Math.max(leftPathSum, rightPathSum) + node.val;
    }

  所以总的来说,要想解决这道题,首先得从小的地方抽离出来,从全局来进行处理,然后在处理具体的情况时,要考虑周全,想到有可能出现的情况。  
  谢谢大家观看我的博客。如果有不明白的地方,或者是文中有错误的地方,欢迎指出,谢谢!如果大家喜欢我的博客,也可以给我点点赞。你们的点赞就是我的动力!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值