[路飞]_二叉树中的最大路径和

785 阅读1分钟

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战

leetcode-124 二叉树中的最大路径和

题目介绍

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

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

给你一个二叉树的根节点 root ,返回其 最大路径和

示例1

image.png

输入: root = [1,2,3]
输出: 6
解释: 最优路径是 2 -> 1 -> 3 ,路径和为 2 + 1 + 3 = 6

示例2

image.png

输入:root = [-10,9,20,null,null,15,7]
输出:42
解释:最优路径是 15 -> 20 -> 7 ,路径和为 15 + 20 + 7 = 42

提示:

  • 树中节点数目范围是 [1, 3 * 10^4]
  • -1000 <= Node.val <= 1000

解题思路

这道题目比较难理解,首先总结一下路径的几点要求:

  1. 任意点出发,到任意点结束
  2. 每个点只经过一次
  3. 至少包含一个节点
  4. 可以不经过根节点 首先我们从一个点来开始分析

1644651987(1).png20 这个点为例,经过 20 这个点的可以有 路径①路径②路径③,如果从 -10 这个点出发,连接 20 的话,接下去只能走 15 或者 7,不可以两个节点都走到,因为这样就会重复经过 20 这个节点了,如果从 15 出发经过 20 的话,可以走到 7 这个节点

因此,我们可以使用递归的思想,记录每个节点的左子节点的最长路径和右子节点的最大路径和,如果当前节点的父节点要走当前节点这条路径的话,那么当前节点能够提供的最大路径和就是 左子节点的最大路径和右子节点的最大路径和 中较大的路径和加上当前节点的节点值,即为当前节点能够提供给父节点的最大路径和

需要注意的是,如果子节点的最大路径和小于 0 的话,如果我们走了这条路径,会导致我们的路径和变小,那么我们就不走这条路径,将子节点的路径和取 0

在遍历每个节点寻找最大路径和的过程中,我们可以定义一个变量 manSum,用于记录以当前节点为根节点的最大路径和(这里就不是当前节点的左右子节点其中一路了,而是当前节点的左右两路的最大路径和),当遍历完整棵树时,这个变量中记录的就是二叉树中的最大路径和

二叉树中的最大路径和.gif

解题代码

var maxPathSum = function(root) {
    // 记录递归过程中的最大路径和
    let maxSum = Number.MIN_SAFE_INTEGER

    let maxPath = root => {
        // 如果当前节点为空,那么可以提供的最大路径和为 0
        if (!root) return 0
        // 获取左节点的最大路径和,如果小于 0 则取 0,说明不要走当前路径
        const left = Math.max(maxPath(root.left), 0)
        // 获取右节点的最大路径和
        const right = Math.max(maxPath(root.right), 0)

        // 如果以当前节点为根节点的最大路径和大于记录的值,则记录最大的路径和
        maxSum = Math.max(maxSum, root.val + left + right)

        // 返回当前节点能够为父节点提供的最大路径和
        return root.val + Math.max(left, right)
    }

    maxPath(root)
    return maxSum
};