思路如下:
一个递归,每个节点需要左右子树返回各自的最大贡献值,注意这个最大贡献值是左右子树各自的根结点+该子树的左右子树中更大的那一个
没理解?行吧,比如上图的例子,我们假设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);
}
}