給定一個非空二叉樹
,返回其最大路徑和。node
路徑 : 一條從樹中任意節點
出發,達到任意節點
的序列。該路徑至少包含一個節點
,且不必定通過根節點。bash
輸入: [1,2,3] 1 / \ 2 3 輸出: 6
輸入: [-10,9,20,null,null,15,7] -10 / \ 9 20 / \ 15 7 輸出: 42
經過 &max 來記錄全局最大值,經過返回ret來記錄遞歸返回的值
code
二叉樹 abc,a 是根結點(遞歸中的 root),bc 是左右子結點(表明其遞歸後的最優解)。
最大的路徑,可能的只有三種路徑狀況:blog
a / \ b c
其中狀況 1,表示若是不聯絡父結點的狀況,或自己是根結點的狀況。
這種狀況是無法遞歸的,可是結果有多是全局最大路徑和。
狀況 2 和 3,遞歸時計算 a+b 和 a+c,選擇一個更優的方案返回,也就是上面說的遞歸後的最優解啦。
另外結點有多是負值,最大和確定就要想辦法捨棄負值(max(0, x))(max(0,x))。遞歸
可是上面 3 種狀況,不管哪一種,a 做爲聯絡點,都不可以捨棄。three
/** * Definition for a binary tree node. * struct TreeNode { * int val; * struct TreeNode *left; * struct TreeNode *right; * }; */ int result = -2147483648; int helper(struct TreeNode* root) { if (root == NULL) return 0; int left = helper(root->left); int right = helper(root->right); int threeNodeSum = root->val + left + right; int twoNodeSum = root->val + max(left, right); int oneNodeSum = root->val; int ret = max(twoNodeSum, oneNodeSum); int currentMax = max(ret, threeNodeSum); result = max(currentMax, result); return ret; } int max(int a, int b) { return a > b ? a : b; } int maxPathSum(struct TreeNode* root){ result = -2147483648; int temp = helper(root); return result; }
#define max(a, b) ((a) > (b) ? (a) : (b)) int maxPath = INT_MIN; int dfs(struct TreeNode *root) { if (root == NULL) { return 0; } // 左子樹的最大和 int left = dfs(root->left); // 右子樹的最大和 int right = dfs(root->right); // 當前節點路徑(不須要聯繫父結點,或自己就已是根結點而無父節點)的最大值 VS 當前全局最大值 maxPath = max(left + right + root->val, maxPath); // 須要聯繫父節點,所以只返回子樹最大分支 return max(0, max(left, right) + root->val); } int maxPathSum(struct TreeNode *root) { // 初始化爲最小可能的整數 maxPath = INT_MIN; // 深度優先遍歷 dfs(root); return maxPath; }