二叉树中最大路径和(详细分析)
题目
给定一个非空二叉树,返回其最大路径和。
本题中,路径被定义为一条从树中任意节点出发,达到任意节点的序列。该路径至少包含一个节点,且不一定经过根节点。
算例
输出: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); }
下一篇:
std::sort 排序使用方法