剑指 Offer II 051. 节点之和最大的路径

在这里插入图片描述
思路如下:

一个递归,每个节点需要左右子树返回各自的最大贡献值,注意这个最大贡献值是左右子树各自的根结点+该子树的左右子树中更大的那一个

没理解?行吧,比如上图的例子,我们假设1这个节点要进入递归,那么1节点返回的值,就是1+3=4,而不是1+2=3。

但是注意,返回的最大贡献值和题目所求的最大值没关系,题目所求的最大值应当有一个全局变量,在每次递归中,访问的根结点与左右子树各自最大贡献值之和才是最大值。

在这里插入图片描述

还是不懂?好吧如图所示,对于-10而言,它能得到的最大值就是左子树的最大贡献值9+右子树的最大贡献值35(20+15)=9+35-10=34。如果-10这个值继续递归,那么他返回的最大贡献值=左子树的最大贡献值与右子树的最大贡献值中更大的那个值+它本身的值

没懂?继续。

对于20而言,它能得到的最大值,就是左子树的最大贡献值15+右子树的最大贡献值7+本身的val=42,这个是题目中索求的变量,但是和20返回的最大贡献值是不一样的,其最大贡献值=左右子树中更大的最大贡献值15+本身20=35,所以它在递归中将最大值更新为42,但返回的最大贡献值为35.

在整个计算中,最大值不参与计算,只参与比较,但最大贡献值每次都参与计算,一切的计算都围绕着最大贡献值来计算,比如最大值是左右最大贡献值之和(要求左右均大于0,不然无视)与结点本身的和,返回的最大贡献值是左右中更大的那个最大贡献值与结点本身的和,这一点搞清楚一切问题就迎刃而解了。

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {

    int max = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        //这道题的思路是:最大贡献值
        //在递归中,寻找左子树的最大路径和与右子树的最大路径和
        //二者与该节点的和求最大值,即为该树上的最大路径和
        DFS(root);
        return max;
    }
    public int DFS(TreeNode root){
        if(root==null) return 0;
        //对于每个节点的计算流程:
        //它需要左右子树给他提供各自的最大值
        //不需要考虑左右子树如何提供最大值,只需要拿到最大值,之后进行对比即可。
        //向上一层返回的是最大值+当前结点

        int left = Math.max(DFS(root.left),0);
        int right = Math.max(DFS(root.right),0); 
        max = Math.max(max,root.val+left+right);//计算结果
        return root.val+Math.max(left,right);
    }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值