1、问题描述
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从二叉树的任意结点出发,到达另一个任意结点的序列。
该节点至少包含一个结点,且不一定经过根结点。
示例 1:
输入: [1,2,3]
1
/ \
2 3
输出: 6
示例 2:
输入: [-10,9,20,null,null,15,7]
-10
/ \
9 20
/ \
15 7
输出: 42
2、解题思路
-
分析:首先,我们来定义节点node的单向最大路径maxpath,单向路径是指该路径只能从节点node的左子树到达节点node或者从节点node的右子树到达节点node,而不能穿过节点node到达其他节点。
-
假设node的左孩子node.left的单向最大路径为leftmaxpah;node的右孩子node.right的单向最大路径为rightmaxpath;则node的单向最大路径maxpath可能为以下几种情况之一:
-
A、leftmaxpath与rightmaxpath的路径和都小于0,则maxpath仅由节点node构成;
-
B、leftmaxpath路径和小于等于0,rightmaxpath路径和大于0,则maxpath由rightmaxpath加上节点node构成;
-
C、rightmaxpath路径和小于等于0,leftmaxpath路径和大于0,则maxpath由leftmaxpath加上节点node构成;
-
D、leftmaxpath与rightmaxpath的路径和都大于0,则maxpath由leftmaxpath和rightmaxpath中最大的那个加上节点node构成;
-
所以,我们可以考虑实现一个函数max_gain(node),用来计算以结点node的单向最大路径maxpath的路径和。
-
(1)如果node为空结点,max_gain(node) = 0;
-
(2)leftmaxpath的路径和left_gain为max_gain(node.left)与0两者之中最大的那个;
-
(3)rightmaxpath的路径和right_gain为max_gain(node.right)与0两者之中最大的那个;
-
(4)如果node非空,max_gain(node) = max{left_gain,right_gain}+node.val
-
-
但是,我们需要注意,node的单向最大路径不一定是二叉树的最大路径,从node的左子树穿过node节点到达右子树的路径也有可能是最大路径(当leftmaxpath与rightmaxpath的路径和都大于0的的时候),其路径和为leftmaxpath+rightmaxpath+node.val,如果这个值比现有的最大路径和还要大,则更新最大路径和。
-
3、代码实现
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
max_sum = float('-inf')
def maxPathSum(self, root: TreeNode) -> int:
self.max_gain(root)
return self.max_sum
def max_gain(self,root:TreeNode) -> int:
if root == None:
return 0
left_gain = max(0,self.max_gain(root.left))
right_gain =max(0, self.max_gain(root.right))
newpath_gain = left_gain + right_gain + root.val
self.max_sum = max(self.max_sum,newpath_gain)
return root.val + max(left_gain,right_gain)