python
a (root)
/ \
b c
对于一个节点node,有3种情况:
- node是最大路径的转折点(U型路径):b+a+c
- node是最大路径的传递者(单边向上):路径为 a+ba + ba+b 或 a+ca + ca+c。把这一段送给父节点,父节点可以继续往上连。:b+a+a的父节点
- node是最大路径的独立点(or null 节点):如果左右子树全是负数,你可能只选你自己 aaa,并把它送给父节点。
- node是最大路径的旁观者:最大路径完全在你的左子树或右子树内部产生,根本不经过node。
"能向上汇报的贡献值"和"当前形成的完整路径和"。
- 计算:当前形成的完整路径和(递归),更新最大值变量
- 返回:能向上汇报的贡献值
python
# 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 maxPathSum(self, root: Optional[TreeNode]) -> int: # 返回root的最大路径
# 全局变量记录遍历过程中产生的最大值。
self.max_sum = float('-inf') # 子函数需要调的父函数的变量self.
def dfs(node):
if not node: # 没有节点,和为 0
return 0
# 1. 向下递归:子树贡献是负数,不选
left_gain = max(dfs(node.left), 0) # 左子节点的最大路径
right_gain = max(dfs(node.right), 0) # 左子节点的最大路径
# 2. "拐弯"的路径: 左边贡献 + 当前节点 + 右边贡献
# 如果左右子树贡献为0,自然就是"单边"or"就node自己"
current_path_sum = node.val + left_gain + right_gain
# 更新全局最大值
self.max_sum = max(self.max_sum, current_path_sum)
# 3. 向上回溯:返回给父节点
# node作为父节点的子节点,(node向下只能单边)
return node.val + max(left_gain, right_gain)
dfs(root) # 在dfs中更新全局变量
return self.max_sum
时间复杂度:O(n),其中 n 为二叉树的节点个数。
空间复杂度:O(n)。最坏情况下,二叉树退化成一条链,递归需要 O(n) 的栈空间。