题目:二叉树中的最大路径和
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
1
/ \
2 3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出: 42
答案:
首先需要明确,路径是不允许走回头路的,例如示例2中,9->-10->20->15->7不是一条路径
解题思路:
参考链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/solution/er-cha-shu-zhong-de-zui-da-lu-jing-he-by-ikaruga/
对每个抽象出来的二叉树 abc,a 是根结点(递归中的 root),bc 是左右子结点(代表其递归后的最优解)。
最大的路径,可能的路径情况:
a
/ \
b c
1.b + a + c。
2.b + a + a 的父结点。
3.c + a + a 的父结点。
注:再重申一次,这里的a、b、c是抽象的当前递归根节点,当前左子树(具体的左子树的子树都已经在之前的递归计算过了,已经抽象综合到本左子树里),当前右子树(也是抽象的)
其中情况 1,表示如果不联络父结点的情况,或本身是根结点的情况。
这种情况是没法递归的,但是结果有可能是全局最大路径和。
情况 2 和 3,递归时计算 a+b 和 a+c,选择一个更优的方案返回,也就是上面说的递归后的最优解。
再解释地具体一点:
-10
/ \
9 20 20 a 可以选择15--20--7作为路径 -10(a)
/ \ / \ 可以抽象为 / \ 也可以选择-10--20--15作为路径 再递归 / \ 时,c表示20(根节点的值)+15(左子树和右子树产生的值较大的一个)
15 7 15 7 b c 也可以选择-10--20--7作为路径 左子树(b) 右子树(c)
所要做的就是递归,递归时记录好全局最大和,返回联络最大和。
class Solution {
public int maxPathSum(TreeNode root) {
int[] maxSum = new int[1]; //使用数组而非int型变量是因为可以将地址传递进去然后直接更改数据(相当于全局变量)
maxSum[0] = Integer.MIN_VALUE;//初始化为最小值。
maxPathSumHelper(root, maxSum);
return maxSum[0];
}
public int maxPathSumHelper(TreeNode root, int[] maxSum) {
if (root == null) {
return 0;
}
int lSum = Math.max(maxPathSumHelper(root.left, maxSum),0); //lSum<0 则赋为0
int rSum = Math.max(maxPathSumHelper(root.right, maxSum),0);//rSum<0 则赋为0
maxSum[0] = Math.max(root.val + lSum + rSum, maxSum[0]);//每次都求一下当前结点与左子树和右子树的最大值,更新全局最大和
return root.val + Math.max(rSum, lSum); //选择左子树和右子树产生的值较大的一个
}
}