标签:blog ar div 问题 代码 log amp c 算法
这道题一眼看上去就是一个递归的算法,对于一棵树,分三种情况,包括根、仅左子树、仅右子树,递归的确认最大值,其中第一种情况(路径中包含根)分析可知它会一直包含根,后两中就复杂点,需要一直递归处理每颗子树。代码如下:
int maxPathSumWithRoot(TreeNode *root) { if (root == nullptr) return 0; int left = maxPathSumWithRoot(root->left); int right = maxPathSumWithRoot(root->right); return max(0, max(left + root->val, right + root->val)); } int maxPathSum(TreeNode *root){ if (root == nullptr) return 0; int maxWithR = maxPathSumWithRoot(root); int lmax = maxPathSum(root->left); int rmax = maxPathSum(root->right); return max(maxWithR, max(lmax, rmax)); }
提交之后发现TLE了,分析发现我早maxPathSum里面的递归是不合理的,因为里面又包含有另一个递归程序,那就成了一个O(n^2)的算法了。事实上,我在上面的程序中考虑的三种情形有重复。简单的说,在父节点中仅含左子树的情形其实就是在左子树(或其某个子树)中包含根的情形,右子树同理,所以递归的看,只存在一种情形,所不同的是根节点在哪的问题。如果我还没写清楚的话,可以试着这样理解,无论是一条怎样的路径,它总是属于某个子树,也就是说,路径中,总会有一个节点作为根节点。
这里比较难以想到的是用一个全局变量在遍历过程中记录结果(所谓全局变量,只要在每次递归中统变化就行,所以利用引用传参来实现),还有一个就是返回值返回的是以当前节点为根节点所能得到的最大路径和。
int helper(TreeNode *root, int &result){ if (root == nullptr) return 0; int left = helper(root->left, result); int right = helper(root->right, result); int cur = root->val + max(left, 0) + max(right, 0); if (cur > result) result = cur; return root->val + max(left, max(right, 0)); } int maxPathSum(TreeNode *root){ if (root == nullptr) return 0; int result = INT_MIN; helper(root, result); return result; }
标签:blog ar div 问题 代码 log amp c 算法
原文地址:http://www.cnblogs.com/hustxujinkang/p/3946855.html