1. 程式人生 > >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
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。

  1. 顯然top-down的遞歸併不適用於這題,因為對於型別(2)的path,它的path sum同時取決於LCA左右sub path的最大值。而這樣的path sum是無法通過top-down傳遞來獲取的。

  2. 所以這裡可以採用bottom-up的遞迴方法:
    對於節點x:
    定義PS1(x)為從x出發向leaf方向的第一類path中最大的path sum。
    定義PS2(x)為以x為LCA的第二類path中的最大path sum。
    顯然如果我們求得所有節點x的PS1 & PS2,其中的最大值必然就是要求的max path sum。

  3. 如何求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。

  4. 需要返回PS1(x)以供上層的節點計算其PS1 & PS2.

  5. 對於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; } }