二叉树中最大路径和(详细分析)

题目

给定一个非空二叉树,返回其最大路径和。

本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
leetcode problem 124

算例


输出:6
解析:2—1—3为最大路径和

在这里插入图片描述
输出:42
解析:15—20—7为最大路径和

算法

在这里插入图片描述
以A为根节点的这棵树的最大路径和可能存在于哪里:

  1. 单纯的存在于以B为根节点的子树中
  2. 单纯的存在于以C为根节点的子树中
  3. A节点到达左子树B中某节点的路径
  4. A节点到达右子树C中某节点的路径
  5. 左子树B中某节点到达右子树C中某节点的路径,必然经过A节点
  6. A节点(假如左、右子树的最大路径均为负数)

因为需要获得从A节点到达其子树中某节点的路径和,很容易想到是深度优先遍历。又因为计算以A为根节点的树的最大路径和计算其子树B、C中的最大路径和函数功能相同,所以设计为递归算法

定义递归函数DFS(root),返回值为经过root节点的单边最大值(单边最大值为root到达其某个子孙节点的最大值,或者root节点自身,即情况3、4、6)。

剩下的情况1、2、5的最大值需要用一个变量 maxval 来统计。

###情况3、4、5
DFS(root) = max(DFS(root.left) + root.val, DFS(root.right) + root.val, root.val)
###情况1、2、5
maxval = max(maxval, DFS(root.left), DFS(root.right), DFS(root.left) + root.val + DFS(root.right))

代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        def dfs(root):
            nonlocal maxval
            if not root:
                return float('-inf')
            ###计算左右子树的最大单边路径
            left = dfs(root.left)
            right = dfs(root.right)
            ###更新maxval
            maxval = max(maxval, left + root.val + right, left, right)
            return max(left + root.val, right + root.val, root.val)
           
        maxval = float("-inf")
        return max(dfs(root), maxval)
        

思路一样,大佬写的DFS函数,但是max直接记录的是root为根节点的最大路径和:

    public int dfs(TreeNode root) {
        if (root == null) {
            return 0;
        }
        //计算左边分支最大值,左边分支如果为负数还不如不选择
        int leftMax = Math.max(0, dfs(root.left));
        //计算右边分支最大值,右边分支如果为负数还不如不选择
        int rightMax = Math.max(0, dfs(root.right));
        //left->root->right 作为路径与历史最大值做比较
        max = Math.max(max, root.val + leftMax + rightMax);
        // 返回经过root的单边最大分支给上游
        return root.val + Math.max(leftMax, rightMax);
    }
  • 0
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值