难度困难
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例 1:
输入: [1,2,3]
1
/ \
2 3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出: 42
解法1:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
/*
树的遍历的题,一般都用 DFS
树的递归解法一般都是递归到叶节点,
然后开始边处理 边回溯到根节点。
求二叉树的最大路径和
难点: 起始位置 和 结束位置 可以为任意位置,
先看一个例子:
4
/ \
11 13
/ \
7 2
最长路径为 7->11->4->13,
假设此时已递归到左叶结点7,
以叶结点7为根结点的子树最大路径和就是7。
然后回溯到结点 11,
如果以结点 11 为根结点的子树,
最大路径和 为 7+11+2=20。
但是,当回溯到结点4的时候,问题来:
对于结点 11 来说,就不能同时取两条路径了,
只能取左路径,或者是右路径,
所以当根结点是4的时候,那么结点 11 只能取其左子结点7,
因为7大于2。
所以,对于每个结点来说,
要先知道: 经过其左子结点的 path之和 大,
还是 经过其右子节点的 path之和 大。
*/
class Solution {
private int result = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxHalfPath(root);
return result;
}
/*
递归函数返回值 定义: 以当前结点为根结点,
到其中的一个叶节点的最大路径之和(左,右两边只取大的那一边)
*/
public int maxHalfPath(TreeNode root) {
/*
在递归函数中,如果当前结点不存在,直接返回0。
否则就分别对其左右子节点调用递归函数,
*/
if (root == null) {
return 0;
}
/*
由于路径和 有可能为负数,这里当然不希望加上负的路径和,
所以先和0相比,取较大的那个,
就是要么不加,加就要加正数。
*/
int left_MaxHalfPath = Math.max(0, maxHalfPath(root.left));
int right_MaxHalfPath = Math.max(0, maxHalfPath(root.right));
/*
可以更新result啦:
以左子结点为终点的最大 path 之和
加上 以右子结点为终点的最大 path 之和,
再加上当前结点值,
这样就组成了一个条完整的路径。
*/
result = Math.max(result, left_MaxHalfPath + root.val + right_MaxHalfPath);
/*
返回: 根结点值 + 只取一边(左边,或右边)
递归函数的返回值: 以当前结点为根结点,
到其中的一个叶节点的最大路径之和(左,右两边只取大的那一边)
*/
return root.val + Math.max(left_MaxHalfPath, right_MaxHalfPath);
}
}