124. 二叉树中的最大路径和 - 力扣(LeetCode) (leetcode-cn.com)
需要注意的问题是像这样子是不能称为路径的。
一个误区是分别求解左右子树的最大路径和,就像上图那样,右子树的最大路径是“∧”这样的,在求解整棵树的最大路径和时是利用不到的。
二叉树的最大路径,一定是经过某颗子树的根节点的,例如下图。
对于这颗子树来说,整个最大路径由三部分组成:
- 左子树上的满足某种性质的路径。
- 根节点。
- 右子树上的满足某种性质的路径。
这里的某种性质的路径为,从根向下出发,到所有节点的路径中,和最大的那条,这个比较好算。
这里的0是考虑到节点为负的情况。
int func(TreeNode* root) {
if (root == nullptr) {
return 0;
}
int lsum = max(0, func(root->left));
int rsum = max(0, func(root->right));
return root->val + max(lsum, sum);
}
由于二叉树的最大路径,一定是经过某颗子树的根节点的,那么我们只需要遍历树中的每个节点,然后计算该节点左右子树的某种性质的路径和,如果最终答案的路径经过该节点,那么最终答案就是func(cur.left)+cur.val+func(cur.right),记该值为A,那么只需要另外设置一个全局变量,记录遍历过程中产生的最大A值即为最终答案。
我们不需要另外一个函数去遍历整棵树,然后在里面调用func,因为func其实就是后续遍历的过程,我们只要在func中记录最大的A就可以了。
int gmax = -2047483648;
int func(TreeNode* root) {
if (root == nullptr) {
return 0;
}
int lsum = max(0, func(root->left));
int rsum = max(0, func(root->right));
gmax = max(gmax, root->val+lsum+rsum);
return root->val + max(lsum, sum);
}
int maxPathSum(TreeNode* root) {
func(root);
return gmax;
}