【LeetCode】124. 二叉树中的最大路径和

30 篇文章 4 订阅
文章介绍了如何使用深度优先搜索(DFS)和动态规划解决二叉树中的最大路径和问题。通过DFS,每个节点的最大路径和是其左右子节点的贡献加上自身值,同时维护全局最大值。动态规划解法则是将路径分为左侧、右侧和当前节点,通过类似数组最大子数组和的思路更新最大上升路径和。
摘要由CSDN通过智能技术生成

题目链接124. 二叉树中的最大路径和
题目描述
在这里插入图片描述
思路:这类题目一般可以通过dfs方式完成,首先我们明白,想要获取这棵二叉树中的最大路径和,那么我们需要知道以每个节点为根的最大路径和,最后找最大的就可以得到答案。那么如何找一个节点的最大路径和呢,一个节点的最大路径和为它的左右两边节点的贡献值当前这个节点值相加的结果,因此,在dfs时候我们需要获取的就是当前节点的最大贡献值,最终每个节点最多会被遍历一次,总的时间复杂度为O(n)。
代码

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

func maxPathSum(root *TreeNode) int {
    // 初始给一个最小值或者root.val,给root.val要考虑root是否为nil
    maxSum := math.MinInt32
    dfs(root,&maxSum)
    return maxSum
}

func dfs(node *TreeNode, maxSum *int) int {
    if node == nil {
        return 0
    }
    // 获取左边子节点的贡献,大于0的才计算curPathSum贡献
    leftVal := max(dfs(node.Left, maxSum), 0)
    // 获取右边子节点贡献
    rightVal := max(dfs(node.Right, maxSum), 0)
    // 记录当前节点的最大路径和
    curPathSum := node.Val + leftVal + rightVal
    // 记录路径和中的最大值
    *maxSum = max(*maxSum, curPathSum)
    // 返回当前节点的最大贡献值
    return node.Val + max(leftVal,rightVal)
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

这题还能用划分子问题的方式思考,变成动态规划,思路和dfs差不多,下面摘自评论区大佬解答,便于理解:

这题目的难点在于理解题意和转化题意。
我们可以结合 数组的最大子数组和 的思路去解题。

1. 「可以从任意节点出发, 到达任意节点」 的路径, 
   一定是先上升( 0 ~ n 个)节点, 到达顶点, 后下降( 0 ~ n 个)节点。
   我们可以通过枚举顶点的方式来枚举路径。
   
2. 我们枚举顶点时, 可以把路径分拆成3部分: 左侧路径、右侧路径和顶点。
   如下面的路径, 顶点为 20, 左侧路径为 6 -> 15, 右侧为 6 -> 7-10
      / \
     9 [20]
       /  \
     [15] [7]
     /    / \
   [6]   4  [6]   

   以当前节点为顶点的路径中, 最大和为 两侧路径的最大和 + 节点的值。
   需要注意的是, 两侧路径也可能不选, 此时取 03. 如何求两侧路径最大和? 看一个类似问题:求数组的最大子数组和。
   动态规划: dp[i] 代表以 nums[i] 为结尾的子数组的最大和。
   转移方程: dp[i] = max(dp[i-1], 0) + nums[i]4. 在树上, 设 dp[C] 代表以当前节点为结尾的最大上升路径和, 
   则我们需要对节点的左右子树做一个选择, 有
   dp[C] = max(max(dp[L], 0), max(dp[R], 0)) + C.val
   式中, C,L,R 分别代指 当前节点、左子节点、右子节点。

5. 最后, 以当前节点为顶点的路径中, 最大的和为
   max(dp[L], 0) + max(dp[R], 0) + C.val。
   我们枚举顶点, 并记录最大答案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

童话ing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值