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
Return6.
思路:
這道題目很難…題目要求求最大路徑和,但是注意到路徑開始節點和結束節點是任意的。查了很多的部落格,對這道題目終於有了一些理解。
1.路徑有4種情況:
(1)左子樹的路徑加上當前節點;
(2)右子樹的路徑加上當前節點;
(3)左右子樹的路徑加上當前節點(相當於一條橫跨當前節點的路徑);
(4)只有自己的路徑。
2.從而可以將path歸納為兩種情況:
(1) root->leaf path中的一段:即題目例子中的1-2或1-3。
(2) 兩個節點之間經過它們lowest common ancestor (LCA)的path:即題目中的2-1-3。
顯然top-down的遞歸併不適用於這題,因為對於型別(2)的path,它的path sum同時取決於LCA左右sub path的最大值。而這樣的path sum是無法通過top-down傳遞來獲取的。
所以這裡可以採用bottom-up的遞迴方法:
對於節點x:
定義PS1(x)為從x出發向leaf方向的第一類path中最大的path sum。
定義PS2(x)為以x為LCA的第二類path中的最大path sum。
顯然如果我們求得所有節點x的PS1 & PS2,其中的最大值必然就是要求的max path sum。如何求PS1(x)、PS2(x)?
(1) PS1(x) 、PS2(x)至少應該不小於x->val,因為x自己就可以作為一個單節點path。
(2) PS1(x) 、 PS2(x)可以從PS1(x->left)和PS1(x->right)來求得:
PS1(x) = max [ max(PS1(x->left), 0), max(PS1(x->right), 0) ] + x->val
PS2(x) = max(PS1(x->left), 0) + max(PS1(x->right), 0) + x->val
注意這裡並不需要PS2(x->left) 以及 PS2(x->right) 因為子節點的2型path無法和父節點構成新的path。需要返回PS1(x)以供上層的節點計算其PS1 & PS2.
對於leaf節點:PS1(x) = PS2(x) = x->val.
java實現
public class Solution7 {
private int max = Integer.MIN_VALUE;// 儲存全域性最大值
public int maxPathSum(TreeNode root) {
findMaxPathSum(root);
return max;
}
public int findMaxPathSum(TreeNode root) {
if (root == null)
return 0;
int left = findMaxPathSum(root.left);
int right = findMaxPathSum(root.right);
//計算PSI(X)
int currSum = Math.max(Math.max(left + root.val, right + root.val), root.val);
//計算PS2(X)
int currMax = Math.max(currSum, left + root.val + right);
max = Math.max(max, currMax);
return currSum;
}
}