题目:
二叉树中的 路径 被定义为一条节点序列,序列中每对相邻节点之间都存在一条边。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。

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

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

解析:
这道题使用递归来解题,重点是递归逻辑的设计以及返回值:
在当前节点(需要拐弯的那个节点)的路径和 = 左子树的最长路径和 + 右子树的最长路径和 + 当前节点的值
返回给父节点的是:
以当前节点为根节点的子树的最长路径和 + 当前节点的值
注意:
如果子树的和是负数,我们宁愿不选择这个子树,比如一个节点值是-10,左子树贡献-5,右子树贡献-3,最好的选择是都不要,返回0

具体代码:

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number}
 */
var maxPathSum = function(root) {
    // 全局变量,用于记录整个树中的最大路径和
    // 初始化为负无穷,确保第一次比较时能被任何节点值更新
    let ans = -Infinity
    
    /**
     * 深度优先搜索函数,递归计算每个节点的贡献值
     * @param {TreeNode} node - 当前处理的节点
     * @return {number} - 返回当前节点能向上贡献的最大路径和
     */
    function dfs(node){
        // 递归终止条件:空节点贡献值为0
        if(node === null){
            return 0
        }
        
        // 递归计算左子树的最大贡献值
        // left表示:以node.left为起点的最大单向路径和
        const left = dfs(node.left)
        
        // 递归计算右子树的最大贡献值
        // right表示:以node.right为起点的最大单向路径和
        const right = dfs(node.right)
        
        // 关键更新:以当前node为根节点的最大路径和
        // 这种情况考虑以node作为"转折点"的完整路径:
        // 可以包含左子树 + 当前节点 + 右子树
        // 这种情况不能向上传递给父节点,所以只用于更新全局答案
        ans = Math.max(ans, left + right + node.val)
        
        // 关键返回:当前节点能向上贡献的最大路径和
        // 这个返回值会被父节点使用,所以只能选择一边:
        // 1. Math.max(left, right) + node.val:选择左或右子树中更大的那个,加上当前节点
        // 2. 与0比较:如果贡献值是负数,就不选择这个子树(贡献0)
        // 这个返回值表示:从当前节点向上的单边最大路径和
        return Math.max(Math.max(left, right) + node.val, 0)
    }
    
    // 从根节点开始深度优先搜索
    dfs(root)
    
    // 返回整个树中的最大路径和
    return ans
}
Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐