时间复杂度:O(n)
解题思路
后序遍历,每次遍历返回该结点可达它父节点的最大路径长度。
选择后序遍历的原因还是因为知道了左右孩子的信息,就可以很好地更新父节点的状态信息。当我们知道左孩子最大路径长度,右孩子最大路径长度后,那么二叉树的直径就可能是左右孩子的最大路径长度之和。而我们返回给父节点的是该结点左右孩子中较大的路径长度和再加1,加1的原因是最长路径又包括了该结点。
AC代码
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func diameterOfBinaryTree(root *TreeNode) (res int) {
var postOrder func(*TreeNode)int
postOrder=func(root *TreeNode)int{
if root==nil{
return 0
}
left:=postOrder(root.Left)//左孩子的可达root结点的最长路径长度
right:=postOrder(root.Right)//右孩子的可达root结点的最长路径长度
res=max(res,left+right)//更新res。注意由于left和right都是路径长度所以不需要减1
return max(left,right)+1//由于孩子的可达父节点的最长路径不能同时经过左右孩子,所以找最大值返回
}
postOrder(root)
return res
}
func max(a,b int)int{
if a>b{
return a
}
return b
}
感悟
后序遍历真的是太重要了,只要是涉及到父子关系的树题,后序遍历一定是一个很好的思路!