這道題算是Divide & Conquer中比較難的了。下面給出top down 和 bottom up 兩種做法。
Top Down的做法是,對于每一點root,求出包含root->left的最大path sum,和包含root->right的最大path sum,將root->left, 與root->right的最大path sum分別與0比較,然后與root->val相加,就是root這一點的最大和。我們記錄一個max_sum的全局變量,對于每一點都這么做,然后update 全局變量。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: The root of binary tree.
* @return: An integer
*/
int maxPathSum(TreeNode * root) {
// write your code here
if(!root){
return 0;
}
findMaxSum(root);
return max_sum;
}
void findMaxSum(TreeNode *root){
if(!root){
return;
}
int leftSum = findUtil(root->left);
int rightSum = findUtil(root->right);
int curSum = root->val + max(0, leftSum) + max(0, rightSum);
if(curSum > max_sum){
max_sum = curSum;
}
findMaxSum(root->left);
findMaxSum(root->right);
}
int findUtil(TreeNode *root){
if(!root){
return 0;
}
int left = findUtil(root->left);
int right = findUtil(root->right);
return root->val + max(0, max(left, right));
}
private:
int max_sum = INT_MIN;
};
Bottom Up的做法是自底向上掃一遍,而掃這一遍的過程中記錄兩個變量,一個是一該點為結尾的最大sum (singlePath sum),一個是總共的最大sum。而途徑該點(say, root) 的max path sum是由root->val + max(left.singlePaht, 0) + max(right.singlePath, 0) 求得的。total max sum需要打擂臺,從下向上返回最大值。
Bottom Up的做法一開始并不好想,在實戰時可以先給出Top Down的做法。這樣便于推出Bottom Up的solution
struct ResultType{
int singlePath, maxPath;
ResultType(int s, int m):singlePath(s), maxPath(m){}
};
int maxPathSum(TreeNode *root) {
// write your code here
if(!root) return 0;
ResultType rs = findSum(root);
return rs.maxPath;
}
ResultType findSum(TreeNode *root){
if(!root) return ResultType(0, INT_MIN);
ResultType leftRs = findSum(root->left);
ResultType rightRs = findSum(root->right);
int singlePath = root->val + max(0, max(leftRs.singlePath, rightRs.singlePath));
int maxPath = root->val + max(0, leftRs.singlePath) + max(0, rightRs.singlePath);
int totalMax = max(maxPath, max(leftRs.maxPath, rightRs.maxPath));
return ResultType(singlePath, totalMax);
}