题目
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
leetcode problem 124
算例
输出:6
解析:2—1—3为最大路径和
输出:42
解析:15—20—7为最大路径和
算法
以A为根节点的这棵树的最大路径和可能存在于哪里:
- 单纯的存在于以B为根节点的子树中
- 单纯的存在于以C为根节点的子树中
- A节点到达左子树B中某节点的路径
- A节点到达右子树C中某节点的路径
- 左子树B中某节点到达右子树C中某节点的路径,必然经过A节点
- A节点(假如左、右子树的最大路径均为负数)
因为需要获得从A节点到达其子树中某节点的路径和,很容易想到是深度优先遍历。又因为计算以A为根节点的树的最大路径和计算其子树B、C中的最大路径和函数功能相同,所以设计为递归算法。
定义递归函数DFS(root),返回值为经过root节点的单边最大值(单边最大值为root到达其某个子孙节点的最大值,或者root节点自身,即情况3、4、6)。
剩下的情况1、2、5的最大值需要用一个变量 maxval 来统计。
###情况3、4、5
DFS(root) = max(DFS(root.left) + root.val, DFS(root.right) + root.val, root.val)
###情况1、2、5
maxval = max(maxval, DFS(root.left), DFS(root.right), DFS(root.left) + root.val + DFS(root.right))
代码
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def maxPathSum(self, root: TreeNode) -> int:
def dfs(root):
nonlocal maxval
if not root:
return float('-inf')
###计算左右子树的最大单边路径
left = dfs(root.left)
right = dfs(root.right)
###更新maxval
maxval = max(maxval, left + root.val + right, left, right)
return max(left + root.val, right + root.val, root.val)
maxval = float("-inf")
return max(dfs(root), maxval)
思路一样,大佬写的DFS函数,但是max直接记录的是root为根节点的最大路径和:
public int dfs(TreeNode root) {
if (root == null) {
return 0;
}
//计算左边分支最大值,左边分支如果为负数还不如不选择
int leftMax = Math.max(0, dfs(root.left));
//计算右边分支最大值,右边分支如果为负数还不如不选择
int rightMax = Math.max(0, dfs(root.right));
//left->root->right 作为路径与历史最大值做比较
max = Math.max(max, root.val + leftMax + rightMax);
// 返回经过root的单边最大分支给上游
return root.val + Math.max(leftMax, rightMax);
}