給定一棵二叉樹,找出最大路徑和。路徑可從任意節點開始,到任意節點結束,但必須沿父子連接(不能跳躍)。路徑至少包含一個節點。
範例:
1
/ \
2 3
輸出:6 (路徑 2→1→3)
int maxSum = INT_MIN; // 全域最大值
// 回傳:以 root 為端點的最大單邊路徑和(可為 0 表示不取)
int dfs(TreeNode* root) {
if (!root) return 0;
int left = max(0, dfs(root->left)); // 負數捨棄,取 0
int right = max(0, dfs(root->right));
// 穿過 root 的路徑和
int cur = root->val + left + right;
maxSum = max(maxSum, cur);
// 回傳單邊最大值供父節點使用
return root->val + max(left, right);
}
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxPathSum(TreeNode* root) {
maxSum = root ? root->val : 0;
dfs(root);
return maxSum;
}
private:
int maxSum;
int dfs(TreeNode* root) {
if (!root) return 0;
int left = dfs(root->left);
int right = dfs(root->right);
int val = root->val;
if (left > 0) val += left;
if (right > 0) val += right;
if (maxSum < val) maxSum = val;
return max(max(left, right), 0) + root->val;
}
};
maxSum 初始化為根節點值或 INT_MIN,應對全負數樹// 單節點
TreeNode* n1 = new TreeNode(-3); // -3
// 全負數
-10
/ \
-2 -3 // -2 (路徑 -2)
// 一般情況
1
/ \
2 3 // 6
// 複雜情況
-10
/ \
9 20
/ \
15 7 // 42 (15→20→7)
「後序遞歸 + 全域維護 + 單邊回傳」是樹上路徑問題的通用模板。關鍵在於區分作為路徑中間節點(可雙邊)與作為路徑端點(只能單邊)的不同角色,並正確處理負數捨棄邏輯。