这是道好题。
题目指明了路径的起点和重点是任意的,可以是一个节点可以是包含父节点和左右子树的路径。问题的关键是,这个左右子树返回的不能是整个树的最大和,而只能是包含了这个子树根节点的一条左路径或者右路径。也不知道这么说是否明白,画图说明是在太麻烦了。。
这么说吧,题目虽然对路径的条件没有限制,但是路径还是要求的,如果直接返回左右子树的结果,那么这个结果可能是来自于一个叶子节点,也可能是整个子树,什么都有可能,当这个结果实际上是由不包含子树的根节点计算出来的,那么接到上一层的时候,用了这个结果,而实际的贡献了结果的节点最终没有形成一条路径,因此是错的。还有一种情况,子树的结果用到了这个子树的根节点,但是同时用到了子树的左右孙子树,这也是不行的,因为接到上层,就形成了一个树杈一样的东西,也不是路径。
那么,到底返回什么东西才行呢,有三种选择,第一,返回这棵子树的根节点,这样接到上层可定还是条路径,二,这个根节点和他的左子树形成的左路径,三,这个跟节点和他的右路径,总之必须包含这个跟节点,且不能开叉,这样才有意义。
还有个问题,你会问那如果一个子树要不不要还好呢?没关系啊,我们用的是先序遍历,祖先自动成型的情况早考虑过了,更新最后的结果和子问题的返回可以分开考虑,多么神奇。
ac代码如下,很简洁:
int res; int tpMaxSum(TreeNode *root){ if(root == NULL) return 0; int mval = 0, lval = 0, rval = 0; mval = root->val; if(root->left) lval = tpMaxSum(root->left); if(root->right) rval = tpMaxSum(root->right); if(lval>0) mval += lval; if(rval>0) mval += rval; if(mval>res) res = mval; return max(root->val, max(root->val+lval, root->val+rval)); } class Solution { public: int maxPathSum(TreeNode *root) { if(root == NULL) return 0; res = 0xc0000000; tpMaxSum(root); return res; } };
leetcode第一刷_Binary Tree Maximum Path Sum,布布扣,bubuko.com
leetcode第一刷_Binary Tree Maximum Path Sum
原文:http://blog.csdn.net/u012792219/article/details/25078353