二叉树的最大路径和——递归

95 阅读1分钟

image.png

递归代码:

  1. recur 函数返回当前节点的最大贡献值, 即路径走左还是走右, 当然如果左右贡献为负, 那自然不再往下走了, 从而得到最大路径和
  2. 由此可以看出如果我们想要得到最大贡献值需要从底往上求,那自然要使用递归实现
  3. 当然,因为我们求的最大路径和可以不经过根节点,所以我们要在递归的过程中维护最大路径和
  4. 即当前节点的值加上左的最大贡献加上右的最大贡献,来得出当前所可以求的最大路径和,当然如果贡献为负,则不计入值
  5. 最后再返回当前节点的最大贡献即可,也就是当前值加上左和右中的最大值,这里依然满足负贡献不计入结果
  6. 递归临界条件,为 nil 时返回 0
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func maxPathSum(root *TreeNode) int {
    maxSum := math.MinInt32
    var maxGain func(*TreeNode) int
    maxGain = func(node *TreeNode) int {
        if node == nil {
            return 0
        }

        // 递归计算左右子节点的最大贡献值
        // 只有在最大贡献值大于 0 时,才会选取对应子节点
        leftGain := max(maxGain(node.Left), 0)
        rightGain := max(maxGain(node.Right), 0)

        // 节点的最大路径和取决于该节点的值与该节点的左右子节点的最大贡献值
        priceNewPath := node.Val + leftGain + rightGain

        // 更新答案
        maxSum = max(maxSum, priceNewPath)

        // 返回节点的最大贡献值
        return node.Val + max(leftGain, rightGain)
    }
    maxGain(root)
    return maxSum
}

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