首先,对于每一颗子树来说,考虑的问题是相同的,因为每一颗子树都会生成一个最大路径和,并且父亲的最大路径和是由其子树决定了,因此,问题的性质为,不同规模下的相同问题,这种情况,比较适合用递归去处理。
对于每一颗子树最大路径和的递归问题,我们首先要考虑,将其分为全局最优和局部最优。
全局最优指的是,在考虑整个问题的最大路径和时,这颗子树是否能最大化收益,那么很显然,对于这颗子树的全局最优为。
而局部最优则考虑的是,当我们考虑这颗子树的父节点的时候,这颗子树能为他父结点带来的收益。那么此时,由于我们要从父节点出发考虑问题,这颗子树递归返回父节点的值,只能是其本身的值,和其一个孩子上的值。既
特殊值判断:注意,局部最优有可能小于0,比如当前节点为负数,那么就应该判断不走入该子树,所以需要把局部最优和0对比,全局最优需要设成负无穷,因为要考虑节点全为负的情况,这种情况下,全局最优可能会小于0
综上所述,代码如下
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func maxPathSum(root *TreeNode) int {
Maxn := math.MinInt32//全局最优
ChildMaxn := 0 //局部最优
var dfs func(root *TreeNode) int
dfs = func(root *TreeNode) int{
if root == nil{//边界条件
return 0
}
//求两个孩子局部最优
left := dfs(root.Left)
right := dfs(root.Right)
//更新全局最优
Maxn = max(Maxn, left + right + root.Val)
//返回局部最优
ChildMaxn = root.Val + max(left,right)
return max(ChildMaxn,0)//注意局部最优可能为负
}
dfs(root)
return Maxn
}