题目描述
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
示例1:
示例2:
解题思路
遇到二叉树的题,如果能用递归就尽量递归吧。
首先回顾递归三步骤:
1、递归终止条件及返回值
2、递推条件
3、返回值分析处理
具体到这道题,采用递归的三个步骤具体化为:
1、递归终止条件为节点为空,返回值为0
2、递推条件:分别递归左右子树,计算左右子树的节点和记为l和r
3、返回值及分析:max(0, l, r) + node.val
这个递归函数实现的是对于一个根节点,通过计算分别计算其左右子树节点和,来看其左右子树是否有正增益。
代码实现
实现部分的核心代码就是self.sum的更新了。
self.sum = max(self.sum, max(0, leftSum)+max(0,rightSum)+root.val)
在更新self.sum时有两个判断,一个是self.sum,另一个包含了两个max加上当前节点的值。
注意此处用的是
max(0, leftSum) + max(0, rightSum) + root.val
这样就是说如果左右子树对于根节点无增益的话,就用0来替代左右子树和,但同时也计算了当前节点的值。
对于这个递归函数,注意其计算顺序,先计算左子树的最大和,再计算右子树的最大和,最后返回
max(0, leftSum, rightSum) + root.val
在计算完左子树最大和后,计算右子树最大和时,代码
self.sum = max(self.sum, max(0, leftSum)+max(0,rightSum)+root.val)
此处最外层max函数的左边是左子树最大和,右边是右子树最大和,self.sun更新后即为左右子树中和较大的那一个。
最后一次更新self.sum时,最外层max函数左边为左右子树最大和中较大的那一个,右边为左子树增益(若左子树和小于0则无增益,用0替代)加上右子树增益加上根节点的和。
class Solution:
def maxPathSum(self, root: TreeNode) -> int:
self.sum = float('-inf')
def dfs(root):
if not root:
return 0
leftSum = dfs(root.left)
rightSum = dfs(root.right)
self.sum = max(self.sum, max(0, leftSum)+max(0,rightSum)+root.val)
return max(0, leftSum, rightSum) + root.val
dfs(root)
return self.sum