题目
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
.
求树当中任意两点间路径上所有点的和的最大值。
可以认为是把树当成图,求任意两点间的最大距离(所有点的值的和)。当然,不能用图的方法来求解,效率太低。
任意路径必然存在一个层最低(最接近根)的点,使得这条路径只存在于以该点作为根的子树上,而与其它部分无关。
该点的值为v(i);
假设经过该点的最大路径为maxpath(i);
以该点左子树的根为一端,到左子树任意位置的最大路径为pathleft(i);
以该点右子树的根为一端,到右子树任意位置的最大路径为pathright(i);
那么
以该点为一端,到该子树任意位置的最大路径path为:path=v(i)+max(pathleft(i),pathright(i),0);
maxpath(i)=max( mathpath(i->left), mathpath(i->right), val(i)+max(pathleft(i),0)+max(pathright(i),0));
由此递推即可。
代码:
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void innerSolve(TreeNode *root,int &maxSum,int &path)
//内部求解;当前子树的根,该子树的最大pathSum,该子树根到任意子节点的最大和
{
if(root==NULL) //空子树
return;
int max_left=INT_MIN,max_right=INT_MIN,path_left=0,path_right=0;
//左、右子树的最大pathSum,左子树根节点到其下任意节点的最大和,右子树根节点到其下任意节点的最大和
innerSolve(root->left,max_left,path_left); //递归
innerSolve(root->right,max_right,path_right);
path=max(path_left,path_right); //最大路径为:左右子树的最大路径取最大(小于零取0)+加根节点
path=path>=0?path+root->val:root->val;
maxSum=(path_left>0?path_left:0)+(path_right>0?path_right:0)+root->val;
//经过该子树的maxSum为经过该子树根+大于0的左右子树的path
maxSum=max(maxSum,max(max_left,max_right)); //与子树的maxSum取最大
}
int maxPathSum(TreeNode *root) {
if(root==NULL)
return 0;
int maxSum=INT_MIN,path=0;
innerSolve(root,maxSum,path);
return maxSum;
}
};