在问 · 算法题解

111. 二叉树的最小深度

简单二叉树广度优先搜索力扣原题 ↗

题目描述

输入二叉树的根节点 root,求它的最小深度。

最小深度指:从根出发走到离根最近的叶子节点,这条路径上的节点个数(含根和该叶子)。叶子节点是左右孩子都为空的节点。

注意只有一个孩子的节点不是叶子,不能在那里停下。空树的最小深度为 0。树用层序数组表示,null 代表空位。

示例 1
输入:root = [3,9,20,null,null,15,7]
输出:2

解释:最近的叶子是 9,路径 3 -> 9 含 2 个节点。

示例 2
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

解释:树退化成一条向右的链,唯一的叶子是 6,路径上共 5 个节点。

数据范围

  • 节点总数在 [0, 10^5] 之间。
  • -1000 <= Node.val <= 1000

解题思路:广度优先搜索

按层 BFS,队列中同时记录节点和它的深度。BFS 按深度从小到大访问节点,所以第一次弹出叶子时,它的深度就是最小深度,可以立刻返回,不必遍历整棵树。

为什么正确

队列中的深度单调不减;弹出一个深度为 d 的节点时,所有深度小于 d 的节点都已弹出且不是叶子。

复杂度分析

时间 O(n),最坏遍历所有节点;空间 O(n)。

易错点

不能照搬最大深度写成 min(左, 右) + 1。当一侧为空时,空的一侧没有叶子,不能被当作深度 0。例如 [2,null,3] 的答案是 2 而不是 1。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        q = collections.deque([(root, 1)])
        while q:
            node, d = q.popleft()
            if not node.left and not node.right:
                return d
            if node.left:
                q.append((node.left, d + 1))
            if node.right:
                q.append((node.right, d + 1))

载入编辑器,自己跑一遍 →

其他解法

广度优先搜索遇到最浅的叶子就返回,通常访问节点更少;深度优先搜索代码更短,空间随树高变化。

解法 2:深度优先搜索 时间 O(n),空间 O(h)

空树返回 0,叶子返回 1。只有一侧子树时,只能走那一侧,返回它的最小深度加一。两侧都有时,取较小值加一。

写法和最大深度对称,但要注意单侧为空不能算作深度 0。它必须遍历整棵树;广度优先搜索遇到第一个叶子就停。

import sys

class Solution:
    def minDepth(self, root):
        sys.setrecursionlimit(10000)
        if not root:
            return 0
        if not root.left:
            return self.minDepth(root.right) + 1
        if not root.right:
            return self.minDepth(root.left) + 1
        return min(self.minDepth(root.left), self.minDepth(root.right)) + 1

二叉树 专题的其他题目

查看 二叉树 全部题目 →