【Hard】二叉树中的最大路径和

304 阅读2分钟

124. 二叉树中的最大路径和 - 力扣(LeetCode) (leetcode-cn.com)

需要注意的问题是像这样子是不能称为路径的。

image.png

一个误区是分别求解左右子树的最大路径和,就像上图那样,右子树的最大路径是“∧”这样的,在求解整棵树的最大路径和时是利用不到的。

二叉树的最大路径,一定是经过某颗子树的根节点的,例如下图。

image.png

对于这颗子树来说,整个最大路径由三部分组成:

  1. 左子树上的满足某种性质的路径。
  2. 根节点。
  3. 右子树上的满足某种性质的路径。

这里的某种性质的路径为,从根向下出发,到所有节点的路径中,和最大的那条,这个比较好算。

这里的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;
}