一日一练:二叉树中的最大路径和

128 阅读1分钟

路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。路径和 是路径中各节点值的总和。给你一个二叉树的根节点 root ,返回其 最大路径和 。

  1. 三个节点

image.png

对于这个二叉树,最大路径和 要比较六个值

  • 根节点 -> 2
  • 左节点 -> -4
  • 右节点 -> 3
  • 根节点 + 左节点 -> -2
  • 根节点 + 右节点 -> 5
  • 左节点 + 根节点 + 右节点 -> 1

所以和最大路径为根节点 + 右节点

  1. 在上述二叉树上添加 另外两个节点 35,如下图,虚线部分为中二叉树

image.png

这个时候同样需要比较六个值:

  • 根节点
  • 右节点
  • 左二叉树
    • 根节点 + 左节点
    • 根节点 + 右节点
  • 根节点 + 右节点
  • 根节点 + 左二叉树的较大路径(不包含 左 -> 根 -> 右)
  • 左二叉树的较大路径(不包含 左 -> 根 -> 右) + 根节点 + 右节点

① ② 中可以看出,之类有个重复比较过程: 左右子树的最大路径

深度优先遍历,对每个子树取最大值,同时返回根 + 左节点或者根 + 右节点中较大值 为其父节点路径做准备。

function maxPathSum(root: TreeNode | null): number {
  let max = Number.MIN_SAFE_INTEGER

  function dp(root: TreeNode | null): number {
    if (root === null) return 0
    const left = root.left && dp(root.left)
    const right = root.right && dp(root.right)
    const leftValue = left! + root.val
    const rightValue = right! + root.val
    // 取最大值
    max = Math.max(
      max,
      leftValue,
      rightValue,
      root.val,
      left! + right! + root.val
    )
    // 为父节点 计算 路径做准备
    return Math.max(leftValue, rightValue, root.val)
  }
  dp(root)

  return max
}