124. 二叉树中的最大路径和
原始题目链接:https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。
路径和 是路径中各节点值的总和。
给你一个二叉树的根节点 root ,返回其 最大路径和 。
解题思路:
这道题需要在递归的同时,记录并比较最大路径,所以需要定义一个功能函数,这个函数的作用是计算当前遍历到的节点的增益,每次都和0比较,因为如果是负数的话,路径总和会变小,不符合题目要求。还需要定义一个存储最大路径和的变量,这里可以是一个类变量,因为每次递归都需要记录当前的最大路径然后和这个变量进行比较并更新,最后返回这个变量就是最大路径和。
这里比较绕的地方是,递归的返回值和当前最大路径和,递归的返回值稍微好理解一点,递归函数的参数是当前节点,每次返回的是当前节点的值和它的左、右子节点当中二选一相加后的和。当前最大路径和 = 当前节点的值 + 当前节点的左子节点的最大贡献值 + 当前节点的右子节点的最大贡献值。具体实现看代码
代码实现:
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
"""
初始化最大路径值为负无穷
"""
self.max_path = float('-inf')
def maxPathSum(self, root: TreeNode) -> int:
# 定义一个计算节点的最大贡献函数
def node_max_gain(node):
# 如果是空节点,则贡献值是0
if not node:
return 0
# 计算节点的增益是从下至上的
# 递归到最下面的叶节点开始计算节点的增益
# 每次和0进行比较,因为节点的值是负值,明显不会是最大路径长度的选择
left_node_max_gain = max(node_max_gain(node.left), 0)
right_node_max_gain = max(node_max_gain(node.right), 0)
# 在递归的计算子节点的最大贡献值的同时,计算当前路径的最大值
# 当前路径的最大值等于当前节点的值+当前节点的左子节点的最大贡献值+当前节点的右子节点的最大贡献值
current_max_path = node.val + left_node_max_gain + right_node_max_gain
# 更新最大路径
self.max_path = max(self.max_path, current_max_path)
# 每次返回当前遍历到的节点的最大贡献值
# 节点的贡献值等于当前节点+左、右子节点的最大值
return node.val + max(left_node_max_gain, right_node_max_gain)
# 调用闭包函数
node_max_gain(root)
# 返回最大路径结果
return self.max_path
参考文献:
https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/solution/124di-gui-de-jing-sui-ji-lu-yi-xia-by-821218213/