时间复杂度:O(n)
解题思路
利用深度优先搜索策略的先序遍历。为了确定宽度,在遍历时需要对结点按照满二叉树性质进行编号。由于先序遍历是先遍历左子树再遍历右子树,所以每层被遍历到的第一个结点一定是最左结点,这样我们就可以在遍历时记录下每一层最左结点的编号,然后在遍历每层的后续结点时根据编号计算当前层宽度,最后比较左右孩子返回的最大宽度和当前层的宽度,谁最大返回谁。
AC代码
时间100%解法
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func widthOfBinaryTree(root *TreeNode) int {
res:=1
layerLeft:=make(map[int]int,1)
var preOrder func(*TreeNode,int,int)
preOrder=func(root *TreeNode,idx,depth int){
if layerLeft[depth]==0{
layerLeft[depth]=idx
}else{
if idx-layerLeft[depth]+1>res{
res=idx-layerLeft[depth]+1
}
}
if root.Left!=nil{
preOrder(root.Left,idx*2+1,depth+1)
}
if root.Right!=nil{
preOrder(root.Right,idx*2+2,depth+1)
}
}
preOrder(root,1,1)
return res
}
官方题解
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func widthOfBinaryTree(root *TreeNode) int {
levelMin:=make(map[int]int,1)
var dfs func(*TreeNode,int,int)int
dfs=func(root *TreeNode,depth,idx int)int{
if root==nil{
return 0
}
if _,ok:=levelMin[depth];!ok{
levelMin[depth]=idx
}
return max(idx-levelMin[depth]+1,max(dfs(root.Left,depth+1,idx*2),dfs(root.Right,depth+1,idx*2+1)))
}
return dfs(root,1,1)
}
func max(x,y int)int{
if x>y{
return x
}
return y
}
感悟
由于需要计算宽度,按照满二叉树的性质对结点编号是一个明智的选择。