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));
int rightSum = max(0, maxPathSumBase(root->right, res));
res = max(res, leftSum + rightSum + root->val);
return max(leftSum, rightSum) + root->val;
}
int maxPathSum(TreeNode* root) {
int res = 0x7FFFFFF;
res = -res - 1;
cout<<res<<endl;
maxPathSumBase(root, res);
return res;
}