题目:
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 root ,返回其 最大路径和 。
示例 1:
输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6
示例 2:
输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42
题解:
我的理解:
class Solution {
int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
search(root);
return maxSum;
}
public int search(TreeNode root) {
//终止条件
if (root == null) {
return 0;
}
//找左边最大值
int left = Math.max(search(root.left),0);
int right = Math.max(search(root.right),0);
//找到三者相加最大值
int three = left + right + root.val;
//更新最大值
maxSum = Math.max(three, maxSum);
//返回左边和右边的最大值
return root.val + Math.max(left, right);
}
}
完整版:
import java.util.*;
class TreeNode {
int val;
TreeNode left = null;
TreeNode right = null;
TreeNode(int val) {
this.val = val;
}
}
class Solution {
int maxSum = Integer.MIN_VALUE;
public int maxPathSum(TreeNode root) {
maxGain(root);
return maxSum;
}
public int maxGain(TreeNode node) {
if (node == null) {
return 0;
}
// 递归计算左右子节点的最大贡献值
// 只有在最大贡献值大于 0 时,才会选取对应子节点
int leftGain = Math.max(maxGain(node.left), 0);
int rightGain = Math.max(maxGain(node.right), 0);
// 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
int priceNewpath = node.val + leftGain + rightGain;
// 更新答案
maxSum = Math.max(maxSum, priceNewpath);
// 返回节点的最大贡献值,因为路径是没有岔路的,返回给父亲的只能是路径。如果按你说的
// return max(结点+左孩子,结点+右孩子,结点+左孩子+右孩子),
// 假如某种情况,一个结点返回了(结点+左孩子+右孩子)这种情况,
// 那么对于他的父亲结点来说,他现在的所谓的路径就是一颗树了,是有分叉的,路径是没有分叉的。
return node.val + Math.max(leftGain, rightGain);
}
}
public class Main {
public static void main(String[] args) {
// root = [-10,9,20,null,null,15,7]
TreeNode root = new TreeNode(-10);
root.left = new TreeNode(9);
root.right = new TreeNode(20);
root.right.left = new TreeNode(15);
root.right.right = new TreeNode(7);
Solution solution = new Solution();
int res = solution.maxPathSum(root);
System.out.println("结果:" + res);
}
}