看完题就懵了,所以在二叉树中可以随意游走,只要保证两个节点之间有边(父子节点连接关系)且每个节点只经过一次就可以,这样可能的情况就有太多了,感觉已经不是一道二叉树的题了,可以当作图的题来解了,懵圈懵圈,果断去看别的大神的解法了。
1、题解:
看完题目后发现,说到底这还是一道关于树的题目,每一条最大路径实际上仍然是一颗以某一节点为根的二叉树,最大路径和为该根节点左右路径和+当前节点值,所以只要以每一个节点为根节点,递归遍历二叉树所有节点,并计算该节点对应的最大路径和,最后返回所有结果中的最大值即可。但需注意,递归返回的内容不是当前节点为根的最大路径和,而应该是当前节点左右子树的路径和中的较大值+当前节点值(因为规定每一个节点只能经过一次,所以在回溯过程中,如果该节点不是最终子树的根节点,那么它只有左/右子树的和可以被计算)。使用二叉树伴侣递归算法,递归的内容实质上就是每一节点对应左右子树的最大路径和。
举例说明一下,用大神的例子来说明,假设二叉树为:
4 / \ 11 13 / \ 7 2
我们比较容易可以知道,最大路径和为7->11->4->13,当程序运行至递归终点节点7时,为叶子节点,其左子树和右子树的最大路径和均为0,返回当前节点值7,之后回溯到节点11,此时的最大路径和为7+11+2=20,之后继续回溯到节点4,此时的最大路径和为max(11+7, 11+2)+4+max(13, 0)结果为35,此时递归到根节点,返回最终结果为35。实现代码如下:
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func maxPathSum(root *TreeNode) int {
var res int=-1 << 31
var maxPath func(r *TreeNode) int
maxPath=func(r *TreeNode) int {
if r==nil { return 0 }
left:=getMax(0, maxPath(r.Left))
right:=getMax(0, maxPath(r.Right))
res=getMax(res, r.Val+left+right)
return r.Val+getMax(left, right)
}
maxPath(root)
return res
}
func getMax(a, b int) int {
if a>=b {
return a
} else { return b }
}
注:每次想调用math库用一下里面的最大最小值都会忘记它是怎么写的,所以干脆看看源码是怎么计算的了,记录如下,感觉还是这个直接的计算简单好记一点:
MaxInt8 = 1<<7 - 1
MinInt8 = -1 << 7
MaxInt16 = 1<<15 - 1
MinInt16 = -1 << 15
MaxInt32 = 1<<31 - 1
MinInt32 = -1 << 31
MaxInt64 = 1<<63 - 1
MinInt64 = -1 << 63
MaxUint8 = 1<<8 - 1
MaxUint16 = 1<<16 - 1
MaxUint32 = 1<<32 - 1
MaxUint64 = 1<<64 - 1