124. Binary Tree Maximum Path Sum的C++解法
阿新 • • 發佈:2018-12-25
乍一看好像很簡單,用遞迴分別求子樹的最大路徑加上根就好了,但實際題目要求路徑可以以任意節點為起點(不一定要加上根)。
分析一下對於指定某個節點為根時,最大的路徑和有可能是哪些情況。第一種是左子樹的路徑加上當前節點,第二種是右子樹的路徑加上當前節點,第三種是左右子樹的路徑加上當前節點(相當於一條橫跨當前節點的路徑),第四種是隻有自己的路徑。然而這四種情況只是用來計算以當前節點根的最大路徑,如果當前節點上面還有節點,那它的父節點是不能累加第三種情況的。
所以遞迴值記錄一、二、四(單路徑)的最大值,因為只要是返回上一層遞迴就意味著上層肯定有其它節點,情況三不能計算在內。每回溯到此層根節點的時候,再另外算情況三的值,和已存在最大值比較即可。
比較好理解的程式碼:
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是不隨著遞迴層數的更新而重新初始化的,而是像一個全域性變數一樣一直不變。