Leetcode 637. 二叉树的层平均值

1.题目描述

给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。

Leetcode 637. 二叉树的层平均值_第1张图片

输入:root = [3,9,20,null,null,15,7]
输出:[3.00000,14.50000,11.00000]
解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。
因此返回 [3, 14.5, 11] 。

Leetcode 637. 二叉树的层平均值_第2张图片

输入:root = [3,9,20,15,7]
输出:[3.00000,14.50000,11.000


提示:

  • 树中节点数量在 [1, 104] 范围内
  • -2^31 <= Node.val <= 2^31 - 1

2.思路分析

2.1 深度优先搜索

1.确定递归函数要处理的参数以及返回值

定义全局变量:totals(存储二叉树每一层的节点值之和)、counts(存储二叉树每一层的节点数)

参数: root(节点)、depth(记录深度)

totals = []
counts = []
def level(root: Optional[TreeNode], depth: int, totals: List[int]) -> None:

2.确定终止条件

当前遍历的节点是空了,那么本层递归就要要结束了,所以如果当前遍历的这个节点是空,就直接return

if not root:
    return

3.单层搜索逻辑

if depth < len(totals):
    totals[depth] += root.val
    counts[depth] += 1
else:
    totals.append(root.val) 中
    counts.append(1)

level(root.left, depth + 1) #左
level(root.right, depth + 1) #右

2.2 广度优先搜索

从根节点开始搜索,每一轮遍历同一层的全部节点,计算该层的节点数以及该层的节点值之和,然后计算该层的平均值。

具体做法:

  • 初始时,将根节点加入队列;
  • 每一轮遍历时,将队列中的节点全部取出,计算这些节点的数量以及它们的节点值之和,并计算这些节点的平均值,然后将这些节点的全部非空子节点加入队列,重复上述操作直到队列为空,遍历结束。

3.代码实现

3.1 深度优先搜索

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
        totals = []
        counts = []

        def level(root: Optional[TreeNode], depth: int) -> None:
            if not root:
                return
            if depth < len(totals):
                totals[depth] += root.val
                counts[depth] += 1
            else:
                totals.append(root.val)
                counts.append(1)

            level(root.left, depth + 1)
            level(root.right, depth + 1)

        level(root, 0)
        result = [total / count for total, count in zip(totals, counts)]
        return result

复杂度分析

  • 时间复杂度:O(n), 二叉树中节点的个数 。
    • 深度优先搜索需要对每个节点访问一次,对于每个节点,维护两个数组的时间复杂度都是O(1),因此深度优先搜索的时间复杂度是 O(n)。
    • 遍历结束之后计算每层的平均值的时间复杂度是O(h),其中 h 是二叉树的高度,任何情况下都满足 h≤n。
      因此总时间复杂度是O(n)。
  • 空间复杂度:O(n), 其中 nn 是二叉树中的节点个数。空间复杂度取决于两个数组的大小和递归调用的层数,两个数组的大小都等于二叉树的高度,递归调用的层数不会超过二叉树的高度,最坏情况下,二叉树的高度等于节点个数。

3.2 广度优先搜索

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def averageOfLevels(self, root: Optional[TreeNode]) -> List[float]:
        result = []
        if not root:
            return result

        from collections import deque
        que = deque([root])

        while que:
            sum_ = 0
            size = len(que)
            for _ in range(size):
                cur = que.popleft()
                sum_ += cur.val

                if cur.left:
                    que.append(cur.left)
                if cur.right:
                    que.append(cur.right)

            result.append(float(sum_/size))
        return result

复杂度分析

  • 时间复杂度:O(n),其中 n 是二叉树中的节点个数。
    • 广度优先搜索需要对每个节点访问一次,时间复杂度是 O(n)。
    • 需要对二叉树的每一层计算平均值,时间复杂度是 O(h),其中 hh 是二叉树的高度,任何情况下都满足h≤n。
      因此总时间复杂度是 O(n)。
  • 空间复杂度:O(n),其中 n是二叉树中的节点个数。空间复杂度取决于队列开销,队列中的节点个数不会超过 n。

你可能感兴趣的:(Leetcode,数据结构,leetcode,算法,深度优先)