leetcode上的题目是这样的:
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 3Return
6
.
这道题目跟那道求数组里子数组和最大的题目类似,使用的是分治方法,有以下三种情况:
对于一个结点,以该结点为根,最大和的路径会出现在
1.根的左子树中
2.根的右子树中
3.包含根的路径,起始与终止结点分别在左、右子树中
思路清晰后,直接写了一段代码结果超时,原因是对于每一个结点都重复计算了3种情况的最大和。其实使用bottom-up可以构建出来,一时没想出来是因为一直在想怎么用小问题的结果直接构成要求的问题,而其实只需要分开做两个,
1.保存3种路径下的最大的和,记为maxOfCurRoot;
2.保存前2种路径下的最大的和,记为singlePathSum。
singlePathSum意思即为不跨越根结点的路径的最大和,因为在这种情况下,该值可以被上层重复使用,这样就不需要再重复计算。因此每一步都更新这两个变量,其中maxOfCurRoot是当前根结点下的最大的和,这个值每一次都与最终的result做比较,如果它大于result,则更新。代码如下:
1 int maxPathSum(TreeNode *root) { 2 // IMPORTANT: Please reset any member data you declared, as 3 // the same Solution instance will be reused for each test case. 4 int result = INT_MIN; 5 if(root==NULL) return result; 6 postorder(root,&result); 7 return result; 8 } 9 int postorder(TreeNode *root,int * result){ 10 if(root==NULL) return 0; 11 int lsum = postorder(root->left,result); 12 int rsum = postorder(root->right,result); 13 int singlePathSum = max(root->val,max(lsum,rsum)+root->val);//不跨越根结点时的最大和 14 int crossPathSum = root->val+lsum+rsum;//跨越根结点的和 15 int maxOfCurRoot = max(singlePathSum,crossPathSum);//求跨越与不跨越情况下的较大者 16 if(maxOfCurRoot>*result) 17 *result = maxOfCurRoot; 18 return singlePathSum; 19 } 20 int max(int a,int b){ 21 return a>b?a:b; 22 }