给定一棵树的根结点,树中每个结点都包含一个整数值val。我们知道树中任意2个结点之间都存在唯一的一条路径,路径值为路径上所有结点值之和。请计算最大的路径值(允许路径为空)。
样例:
-10 / | \ 2 3 4 / \ 5 -1 / 6 / -1 最大的路径值为13,相应的路径为5到6之间的路径。
扩展:此题算法也可用来解决另一个非常常见的面试题“树的直径”(求树中任意两结点路径的长度的最大值)。可以认为树中每个结点的val值为1,那么求最长路径相当于求路径值最大的路径。
思路还是跟之前那个一样的,这回是任意叉树了,改一下就好了。
/*
树结点的定义(请不要在代码中定义该类型)
struct TreeNode {
int val;
vector<TreeNode*> children; //该结点的儿子结点
};
*/
void solve(TreeNode* root,int& maxSum,int& halfSum);
void update(int& m1,int& m2,int n);
int maxTreePathSum(TreeNode *root) {
int maxSum=0,halfSum=0;
solve(root,maxSum,halfSum);
return max(0,maxSum);
}
void solve(TreeNode* root,int& maxSum,int& halfSum)
{
if ( !root )
{
maxSum=halfSum=0;
return;
}
halfSum=root->val;
maxSum=root->val;
int maxPath1=0,maxPath2=0;
for(int i=0;i<root->children.size();i++)
{
TreeNode* child=root->children[i];
int lMax=0,lHalf=0;
solve(child,lMax,lHalf);
halfSum=max(halfSum,root->val+lHalf);
maxSum=max(maxSum,lMax);
update(maxPath1,maxPath2,lHalf);
}
maxSum=max(maxSum,maxPath1+maxPath2+root->val);
}
void update(int& m1,int& m2,int n)
{
if ( n >= m1 )
{
m2=m1;
m1=n;
}
else if ( n >=m2 )
m2=n;
}