二叉树的层平均值 Average of Levels in Binary Tree ⭐️
LeetCode每日一题 2020.09.12
Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array.
Example:
1 2 3 4 5 6 7 8 9 Input: 3 / \ 9 20 / \ 15 7 Output: [3, 14.5, 11] Explanation: The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11].
note: The range of node’s value is in the range of 32-bit signed integer.
题目大意 按照题目大意需要计算二叉树每层所有节点的平均值, 必然需要遍历整个二叉树节点, 所以自然想到DFS(深度优先检索)和BFS(广度优先检索)两种方式。
解题思路 方式一: DFS 使用深度优先检索算法计算二叉树的层平均值, 首先定义两个数组, 第一个数组(counts)用于存储二叉树的每一层的节点数, 第二个数组(sums)用于存储二叉树的每一层的节点值之和。遍历完整个二叉树之后,第 i 层的平均值即为 sums[i]/counts[i].
方式二: BFS 使用广度优先检索算法计算二叉树的层平均值. 用层序遍历的方法, 维护一个队列去遍历节点. 用 for 循环控制一层的节点逐个出列, 节点值累加求和. 节点出列的同时, 下一层的子节点加入队列, 在 for 循环结束时,队列中就全是下一层的节点. 此时当前层的求和也好了, 除以当前层的节点个数, 就是当前层的平均值, 加入结果数组. 接着处理下一层的节点, 重复以上步骤, 就构建好了结果数组.
广度优先检索算法通过使用队列存储待访问节点, 只要保证在每一轮遍历时, 当前队列中的节点是同一层的所有节.
第一步, 将根节点加入队列; 每一轮遍历, 将队列中的所有节点取出, 计算节点的数量以及节点值之和, 同时计算节点的平均值, 然后将节点的全部非空子节点重新加入队列, 直到队列为空, 遍历结束. 代码 DFS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 type data struct {sum, count int }func averageOfLevels (root *TreeNode) []float64 { levelsData := []data{} var dfs func (node *TreeNode, level int ) dfs = func (node *TreeNode, level int ) { if node == nil { return } if level < len (levelsData) { levelsData[level].sum += node.Val levelsData[level].count++ } else { levelsData = append (levelsData, data{node.Val, 1 }) } dfs(node.Left, level+1 ) dfs(node.Right, level+1 ) } dfs(root, 0 ) averages := make ([]float64 , len (levelsData)) for i, d := range levelsData { averages[i] = float64 (d.sum) / float64 (d.count) } return averages }
BFS 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 func averageOfLevels (root *TreeNode) (averages []float64 ) { nextLevel := []*TreeNode{root} for len (nextLevel) > 0 { sum := 0 curLevel := nextLevel nextLevel = nil for _, node := range curLevel { sum += node.Val if node.Left != nil { nextLevel = append (nextLevel, node.Left) } if node.Right != nil { nextLevel = append (nextLevel, node.Right) } } averages = append (averages, float64 (sum)/float64 (len (curLevel))) } return }
复杂度分析 时间复杂度: O ( n ) O(n) O ( n ) , 其中 n 是二叉树中的节点个数。 空间复杂度: O ( n ) O(n) O ( n ) , 其中 n 是二叉树中的节点个数。