LeetCode124 二叉树中的最大路径和

目录

题目

分析

解答

自测

补充


题目

链接:124. 二叉树中的最大路径和

路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

路径和 是路径中各节点值的总和。

给你一个二叉树的根节点 root ,返回其 最大路径和 。

示例 1:

输入:root = [1,2,3]
输出:6
解释:最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例 2:

输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

  • 树中节点数目范围是 [1, 3 * 104]
  • -1000 <= Node.val <= 1000

分析

        本题考察的内容为树的递归遍历,题目中明确了树不为空,但是节点可能为负的情况,即左左右孩子不一定对父节点都是增益效果,所以我们需要对其进行判断。

        假设现在有一个子树,节点分别为a、b、c,借助DP的思路,我们将问题拆分成2种大的情况。
            a
           / \
         b   c
(1)a为最终结果所确定的子树的一部分
        (1.1) a选取左右子树的最大路径和较大的那个组成一个路径。
        (1.2) 左右子树均的最大路径和均为负数,均不选取,a为最终路径的叶子节点。
(2)a为最终结果所确定的子树的根节点
        (2.1) 左右子树的最大路径和均为正数,a的左右子树都在最终结果中。
      (2.2)左右子树的最大路径和存在负数(可能一个为负,可能都为负),a只有左/右子树,或只有根节点。

解答

        对于上文中分析后得出的第一种情况,我们用max[a]代表a节点能贡献给父节点的最大路径,第二种情况将MAX[a]代表到a节点为止的最大路径和,于是有:
        max[a] = Math.max(max[a.left]+a,max[a.right]+a,a);
        MAX[a] = Math.max(max[a],a+max[b]+max[c]);
        MAX(最终结果) = Math.max(MAX(当前最大值),MAX[a]);

        我们通过深度优先遍历DFS,遍历每一个节点,每次递归结束后将max(a)返回给上一层,
用于作为子树的最大路径和参与a的父节点的相关计算。

class Solution {
    // 题目允许节点值为负数,这里进行特殊处理
    int MAX = Integer.MIN_VALUE;
    public int maxPathSum(TreeNode root) {
        dfs(root);
        return MAX;
    }
    public int dfs(TreeNode root){
        if(root==null){
            return Integer.MIN_VALUE;
        }
        // 计算左右子树能提供的最大路径
        int left = dfs(root.left);
        int right = dfs(root.right);
        // 计算第一种情况,即当前节点作为最终结果的子路径,此时只能在左右子树中选较大的那个,或者都不选取
        int max = Math.max(Math.max(left,right)+root.val,root.val);
        // 计算第二种情况,即当前节点作为最终结果的根节点,那么还需要在上一步的基础上再将其与
        // 根节点+左子树+右子树进行比较,并将结果再与当前的最大路径和进行比较即可。
        MAX = Math.max(MAX,Math.max(max,root.val+left+right));
        return max;
    }
}

时间复杂度:O(n)
空间复杂度:O(n)

自测

        题目给出的数据范围表明,树不为空,那么空树的情况我们可以直接跳过。但需要注意这里树的节点是可能为负数的,所以我们需要考虑到树的节点全为负,或部分为负数的情况。另外树的特殊情况,如每个节点都只有左子树这样的情形也需要考虑到。

补充

相关题目:543. 二叉树的直径

这题求的是路径的长度,我们将本题中计算最大和的步骤调整为每次递归返回时+1即可得到结果。

class Solution {
    int res=0;
    public int diameterOfBinaryTree(TreeNode root) {
        def(root);
        return res;
    }

    public int def(TreeNode root){
        if(root==null) return 0;
        int left=def(root.left);
        int right=def(root.right);
        res = Math.max(left+right,res);
        return Math.max(left,right)+1;
    }
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值