[leetcode] BinaryTreeMaximumPathSum

Binary Tree Maximum Path Sum

  • 題意:從二叉樹的任意一個起點出發,到另一個點所經過的路徑和最大。注意,這裏的路徑就包含了一個點最多隻能經過一次。
  • 分析:我們最大路徑一定是要路過某些點的(不支持路徑長度爲0)。我們的路徑都可以抽象成如下所示的路徑。左邊的長度和右邊的長度都可以爲0。所以我們就是要計算所有類似路徑的長度之和。
  • 按照上面的思路,我們已經將問題轉化成了所有類似這種形狀路徑中的最大值。
  • 那麼我們怎麼計算這種路徑的最大值呢?
  • 對於我們的每個節點來說,他所能產生的路徑長度就是以左孩子爲根結點的單邊路徑最大值+以右孩子爲跟節點的單邊路徑最大值+當前節點的value。注意左子樹或者右子樹中的最大值必須大於等於0.因爲我們可以選擇不要左子樹,從該節點開始。
  • 什麼是單邊路徑?就是類似我們圖中用括號擴起來的部分。就是不能有轉折,因爲有轉折的話就不能向上再走了,否則會有重複路徑。
  • 那麼如何計算左孩子爲跟節點的單邊路徑最大值呢?
  • 我們最終返回的結果就是所有路徑長度中的最大值。
  • 僞代碼
    • MaxPathSumBase
    • 輸入:根節點root, res=-INF
    • 輸出包含根節點的單邊路徑最大值
    • 如果根節點爲NULL,返回0
    • 計算左子樹的最大值 LMax = max(0, LMax)
    • 計算右子樹的最大值 RMax = max(0, RMax)
    • 計算包含本節點的值類似倒V型的路徑中的最大值。res = max(res, LMax + RMax + root->value)
    • 返回當前子樹的形成的單邊的最大路徑。max(LMax, RMax) + root->value
  • 代碼:
int maxPathSumBase(TreeNode* root, int& res){
        if(root == NULL)
            return 0;
        int leftSum = max(0, maxPathSumBase(root->left, res)); // 如果左子樹的和小於0, 則忽略不計
        int rightSum = max(0, maxPathSumBase(root->right, res)); // 如果右子樹的和小於0, 則忽略不計
        res = max(res, leftSum + rightSum + root->val); // 結果左子樹+右子樹+root 因爲左子樹和右子樹>=0;
        return max(leftSum, rightSum) + root->val;  // 如果結果在上面,則肯定需要加入root節點的value。

    }
    int maxPathSum(TreeNode* root) {
        int res = 0x7FFFFFF;
        res = -res - 1;
        cout<<res<<endl;
        maxPathSumBase(root, res);
        return res;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章