链接:http://leetcode.com/onlinejudge#question_124
原题:
Given a binary tree, find the maximum path sum.
The path may start and end at any node in the tree.
For example:
Given the below binary tree,
1 / \ 2 3
Return 6
.
解题思路:
一上来,我是借鉴求数组最大子序列和的方法,来解这个问题的,但是只能过小数据,大数据老是TLE
我的代码
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxPathSum(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if (root == NULL)
return 0;
max = root->val;
maxPath(root);
return max;
}
private:
void maxPath(TreeNode *root) {
if (root == NULL)
return;
vector<int> leftPath;
int leftTail = 0;
subPath(root->left, leftPath, leftTail);
vector<int> rightPath;
int rightTail = 0;
subPath(root->right, rightPath, rightTail);
if (leftTail + root->val + rightTail > max)
max = leftTail + root->val + rightTail;
maxPath(root->left);
maxPath(root->right);
}
void subPath(TreeNode *root, vector<int> &path, int &maxTail) {
if (root == NULL)
return;
path.push_back(root->val);
if (root->left || root->right) {
subPath(root->left, path, maxTail);
subPath(root->right, path, maxTail);
} else {
int sum = 0;
for (vector<int>::reverse_iterator itr = path.rbegin(); itr != path.rend(); itr++) {
sum += *itr;
if (sum > max)
max = sum;
if (sum < 0)
sum = 0;
}
if (sum > maxTail)
maxTail = sum;
}
path.pop_back();
}
int max;
};
后来是借鉴了这位大牛( http://blog.csdn.net/zyfo2/article/details/8636205)的代码,才过的。
具体思路:
对于每一个节点来说,最大路径和只有出现在这三种情况:
1) 在其左子树当中;
2) 在其右子树当中;
3) 最大和路径经过这个节点。
现在考虑第三情况,其它两种都是递归可得的子问题,
不妨设该节点为Node,左子树到该节点的任意一条路径为 leftPath = {L1, L2, ..., Ln, Node}
同样,右子树到该节点的任意一条路径为 rightPath = {Node, Rm, ..., R2, R1}
现在要求过Node的最大路径和,那么可以从两边往中间走,这样正好可以用递归实现。
int rightTail = 0;
for (int i=1; i<=m; i++) {
rightTail += Ri;
if (rightTail < 0)
rightTail = 0
}
int leftTail = 0;
for (int i=1; i<=n; i++) {
leftTail += Li;
if (leftTail < 0)
leftTail = 0
}
sum = leftTail + Node + rightTail
原理:如果路径要想向左右两个扩展,那么扩展部分的和肯定是个正值,否则路径和不会变大。
AC的代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxPathSum(TreeNode *root) {
// Start typing your C/C++ solution below
// DO NOT write int main() function
if (root == NULL)
return 0;
int max = root->val;
getPathSum(root, max);
return max;
}
private:
int getPathSum(TreeNode *root, int &max) {
if (root == NULL)
return 0;
int leftSum = getPathSum(root->left, max);
int rightSum = getPathSum(root->right, max);
if (leftSum + root->val + rightSum > max)
max = leftSum + root->val + rightSum;
int subPathSum = leftSum > rightSum ? leftSum : rightSum;
subPathSum += root->val;
return subPathSum > 0 ? subPathSum : 0;
}
};