求路径最大和。
递归:大问题分解成小问题。
本题:求当前树路径最大和分解为求左子树路径最大和以及右子树路径最大和:max = root.val + left + right
; left和right分别代表左右子树的最大值。
如果这样分解,因为求出左右子树最大值后需要和根节点相加,那么我们的路径需要包含根节点。
以根节点为-3的左子树为例,如果他的最大路径和是 左树-> -3 ->右树,那他就不可能再经过整个树的根节点8。也就是说,这棵子树的最大路径和不可以表示为root.val + left + right;
。为了可以使得子树路径和8相连,那么我们子树的路径只能为 左树 -> -3( -> 8), 或者 右树-> -3( -> 8),路径和表示为:root.val + Math.max(left, right);
public int helper(TreeNode root){
if(root==null) return 0;
int left = Math.max(helper(root.left),0);
int right = Math.max(helper(root.right),0);
return root.val+Math.max(left,right);
}
以上出于递归函数大问题与小问题之间联系的考虑找到了关系式,那如果最大路径和确实不包含根节点呢?比如
路径应为 15 -> 50 ->7。
在上面以-3为根节点的子树中,路径和表示为:root.val + left;
或者root.val + right;
根据我们对递归函数的定义,left和right分别代表左右子树的最大值。那其实我们可以算一下root.val + left + right
(上面解释过不这么递归的原因)。用全局变量max代表最大值,每一次递归的更新这个值,最后输出的就是结果了。
int max = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
helper(root);
return max;
}
public int helper(TreeNode root){
if(root==null) return 0;
int left = Math.max(helper(root.left),0);
int right = Math.max(helper(root.right),0);
max = Math.max(max,root.val+left+right);//偷偷算一下 root.val + left + right
return root.val+Math.max(left,right);//大问题的分解并没有变,我们只是偷偷算一下 ⬆
}