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; }