[leetcode]Binary Tree Maximum Path Sum

时间:2023-03-08 23:26:44
[leetcode]Binary Tree Maximum Path Sum

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

The path may start and end at any node in the tree.

For example:
Given the below binary tree,

       1
/ \
2 3

Return 6.

递归求解。

maxPathSum(root)跟maxPathSum(root.left)和maxPathSum(root.right)之间的关系:

root左子树的maxPath,右子树的maxPath以及根节点之间无法建立直接递归关系。也就是说以下的递推式不成立:

maxPathSum(root) = max{ maxPathSum(root.left), maxPathSum(root.right), maxPathSum(root.left) + maxPathSum(root.right) + root.val }

然而,按照动态规划的思路,root的结果跟其左右子树的结果之间应该是存在递推关系的:

maxPathSum(root) = F( maxPathSum(root.left), maxPathSum(root.right), root )

只是,这个root节点加进来之后如何影响最优解?进一步梳理思路:

F( maxPathSum(root.left), maxPathSum(root.right), root )

/ max{maxPathSum(root.left), maxPathSum(root.right)},                                                                   if root 将不包含在最长路径中

=  {

\ max{maxPathSum(root.left), maxPathSum(root.right), max path sum of the path includes root},    if root 将包含在最长路径中

问题将归结为:求出一条包含root节点的最长路径,并比较该路径的长度与其左右子树的最长路径长度。

所以,在递归过程中,我们需要计算两个值:

1)包含节点在内的最长路径(只可能跟该节点的左子树或者右子树相关);

2)该节点作为根节点的子树的最长路径和;

定义class描述这个递归中间结果:

class max_val {
int max_path_include_root_half_tree; // 辅助值
int max_path_sum; // 待求解值 public void set(int x) {
max_path_include_root_half_tree = max_path_sum = x;
}
}

递归过程:

private void maxPathSum(TreeNode root, max_val max_vs) {
if (root == null) {
max_vs.set(-2147483647 >> 2);
return;
} if (root.left == null && root.right == null) {
max_vs.set(root.val);
return;
} max_val left_ = new max_val();
maxPathSum(root.left, left_); max_val right_ = new max_val();
maxPathSum(root.right, right_); int a = left_.max_path_include_root_half_tree + root.val;
int b = right_.max_path_include_root_half_tree + root.val;
int c = root.val;//a,b,c中包含root的值,并且最多包含了左子树或者右子树,这类路径可用于组成包含父节点的路径
int d = a + right_.max_path_include_root_half_tree;
int f = left_.max_path_sum;
int g = right_.max_path_sum; max_vs.max_path_include_root_half_tree = max(new int[] { a, b, c });// 包含root的最长路径 max_vs.max_path_sum = max(new int[] { a, b, c, d, f, g });// root作为根节点的树的最长路径和 }

最终求解:

	public int maxPathSum(TreeNode root) {
// Start typing your Java solution below
// DO NOT write main() function
max_val mv_l = new max_val();
maxPathSum(root, mv_l); return mv_l.max_path_sum;
}