0111.二叉树的最小深度
难度:🟢 简单
标签:树
、深度优先搜索
、广度优先搜索
、二叉树
、递归
题目描述
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6]
输出:5
解题思路
核心思想
本题的核心是找到从根节点到最近叶子节点的路径长度。这与“最大深度”不同,关键在于对“最小”的理解。如果一个节点只有一个子节点,那么它的最小深度不能简单地认为是 1(因为它本身不是叶子节点),而必须是 1 +
其唯一子树的最小深度。
思路选择
深度优先搜索 (DFS),通过递归实现,是解决此问题的直观方法。我们需要定义一个函数来计算以任何给定节点为根的树的最小深度,并正确处理只有一个子节点的情况。
关键步骤
递归的终止条件 (Base Case):如果当前节点
root
为null
,它不构成路径,深度为 0。处理左子树为空的情况:如果
root.left
为null
,说明要找到叶子节点,必须继续在右子树中寻找。因此,最小深度为1 + minDepth(root.right)
。处理右子树为空的情况:同理,如果
root.right
为null
,必须在左子树中继续寻找。最小深度为1 + minDepth(root.left)
。处理左右子树都存在的情况:如果左右子树都存在,那么我们就可以在两条路径中选择较短的一条。最小深度为
1 + Math.min(minDepth(root.left), minDepth(root.right))
。叶子节点:当一个节点的左右子树都为
null
时,它符合步骤 2 和 3 的逻辑,并最终会返回 1,这符合叶子节点深度为 1 的定义。
代码实现
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var minDepth = function (root) {
// Base Case: 空树深度为 0
if (root === null) return 0;
// 如果左子树为空,则必须从右子树找叶子节点
if (root.left === null) return minDepth(root.right) + 1;
// 如果右子树为空,则必须从左子树找叶子节点
if (root.right === null) return minDepth(root.left) + 1;
// 如果左右子树都不为空,则取两者中较小的深度
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
};
复杂度分析
时间复杂度:O(n) 其中 n 是树的节点总数。在最坏的情况下,我们需要访问树中的每一个节点一次。
空间复杂度:O(h) 其中 h 是树的高度。空间复杂度主要由递归调用栈的深度决定。在最坏情况下(树退化为一条链),空间复杂度为 O(n);在最好的情况下(一个完全平衡的树),空间复杂度为 O(log n)。
相关题目
总结
本题是二叉树递归的经典题目,但比求最大深度多了一个需要细心处理的逻辑点。解题的关键在于准确理解“最小深度”的定义——路径必须终止于一个叶子节点,从而正确处理只有一个子树的节点情况。