1. 程式人生 > >124. Binary Tree Maximum Path Sum的C++解法

124. Binary Tree Maximum Path Sum的C++解法

乍一看好像很簡單,用遞迴分別求子樹的最大路徑加上根就好了,但實際題目要求路徑可以以任意節點為起點(不一定要加上根)。

分析一下對於指定某個節點為根時,最大的路徑和有可能是哪些情況。第一種是左子樹的路徑加上當前節點,第二種是右子樹的路徑加上當前節點,第三種是左右子樹的路徑加上當前節點(相當於一條橫跨當前節點的路徑),第四種是隻有自己的路徑。然而這四種情況只是用來計算以當前節點根的最大路徑,如果當前節點上面還有節點,那它的父節點是不能累加第三種情況的。

所以遞迴值記錄一、二、四(單路徑)的最大值,因為只要是返回上一層遞迴就意味著上層肯定有其它節點,情況三不能計算在內。每回溯到此層根節點的時候,再另外算情況三的值,和已存在最大值比較即可。
比較好理解的程式碼:

class Solution {
public:
    int maxres=INT_MIN;
    int maxPathSum(TreeNode * root) {
        helper(root);
        return maxres;
    }
    int helper(TreeNode * root) {
        if(root == NULL) return 0;
        int left = helper(root->left);
        int right = helper(root->right);
        //單路徑的最大值
        int currSum = max(max(left + root->val, right + root->val), root->val);
        //單路徑和多路徑的最大值
        int currMax = max(currSum, left + right + root->val);
        //更新
        maxres = max(currMax, maxres);
        //只返回單路徑的共上一層根節點使用
        return currSum;
    } 
};

還有一個思路一樣但是更快一點的程式碼:

class Solution {
public:
    int help(TreeNode* root, int &maxres){
        if (!root) return 0;
        int l=max(0, help(root->left, maxres));
        int r=max(0, help(root->right, maxres));
        maxres = max(maxres, root->val+l+r);
        return max(root->val, root->val+max(l, r));
    }
 
    int maxPathSum(TreeNode* root) {
        int maxres=INT_MIN;
        help(root, maxres);
        return maxres;
    }
};

有兩點,一個是用max(0,A)直接排除和小於0的情況,一個是用int&代替了全域性變數,加了引用的maxres是不隨著遞迴層數的更新而重新初始化的,而是像一個全域性變數一樣一直不變。