【前端刷题】124.二叉树中的最大路径和(HARD)

94 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情

题目(Binary Tree Maximum Path Sum)

链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum
解决数:1395
通过率:44.9%
标签:树 深度优先搜索 动态规划 二叉树 
相关公司:facebook amazon bytedance 

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

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

给你一个二叉树的根节点 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

思路

解题思路

  • 题目中的路径最主要的特点是路径有可能同时经过一个节点的左右子节点
  • 当路径到达某个节点时,该路径既可以前往它的左子树,也可以前往它的右子树;但是如果路径同时经过它的左右子树,那么就不能经过它的父节点
  • 为什么用后序遍历,因为对于一个二叉树节点,先计算左子树和右子树的最大路径和,然后加上自己的值,就可以得出新的最路径和

代码

/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxPathSum = function (root) {
  // 最大路径和 初始化值为数字最小值
  let maxSum = Number.MIN_SAFE_INTEGER;
  /**
   * 函数定义:计算从根节点 root 为起点的最大单边路径和
   */
  const oneSideMax = (root) => {
    // 遍历到null节点,收益0
    if (root == null) return 0;

    // 左子树提供的最大路径和
    const left = oneSideMax(root.left);
    // 右子树提供的最大路径和
    const right = oneSideMax(root.right);

    // 当前子树内部的最大路径和
    const innerMaxSum = left + root.val + right;
    // 挑战最大纪录
    maxSum = Math.max(maxSum, innerMaxSum);

    // 当前子树对外提供的最大和
    const outputMaxSum = root.val + Math.max(left, right);
    // 对外提供的路径和为负,直接返回0。否则正常返回
    return outputMaxSum < 0 ? 0 : outputMaxSum;
    // 也可以写成如下
    return Math.max(0, outputMaxSum);
  };
  oneSideMax(root);
  return maxSum;
};