题目描述
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
示例 1:
输入: root = [3,9,20,null,null,15,7]
输出: 2
示例 2:
输入: root = [2,null,3,null,4,null,5,null,6]
输出: 5
核心概念:二叉树的最小深度
二叉树的最小深度定义是:从根节点到最近的叶子节点的最短路径上的节点数量。
⚠️ 关键注意点:叶子节点是指左右子节点都为空的节点。比如根节点只有左子树时,最小深度不是 1,而是左子树的深度 + 1(因为根节点本身不是叶子节点)。
解题思路(两种常用方法)
方法 1:深度优先搜索(DFS,递归实现)
这是最直观的递归思路,核心是分情况处理左右子树:
-
边界条件:如果根节点为空,返回 0(空树深度为 0)。
-
递归处理左右子树:
- 若左子树为空、右子树非空:最小深度 = 右子树的最小深度 + 1(当前节点不是叶子,需依赖右子树)。
- 若右子树为空、左子树非空:最小深度 = 左子树的最小深度 + 1。
- 若左右子树都非空:最小深度 = min (左子树最小深度,右子树最小深度) + 1(取更小的子树深度,加当前节点)。
方法 2:广度优先搜索(BFS,层序遍历)
这是更高效的方法(找到第一个叶子节点就直接返回,无需遍历整棵树):
-
边界条件:根节点为空,返回 0。
-
用队列存储每一层的节点,初始化深度为 0。
-
逐层遍历节点:
- 每处理一层,深度 + 1。
- 遍历当前层的所有节点,若某个节点是叶子节点(左右都为空),直接返回当前深度(这就是最小深度)。
- 若不是叶子节点,将非空的左 / 右子节点加入队列,继续下一层遍历。
完整可运行代码
方法 1:DFS 递归实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
int minDepth(TreeNode* root) {
// 边界条件:空树深度为0(修复你代码中return无值的问题)
if (root == nullptr) return 0;
// 情况1:左子树为空,右子树非空
if (root->left == nullptr) {
return minDepth(root->right) + 1;
}
// 情况2:右子树为空,左子树非空
if (root->right == nullptr) {
return minDepth(root->left) + 1;
}
// 情况3:左右子树都非空,取最小值+1
return min(minDepth(root->left), minDepth(root->right)) + 1;
}
};
方法 2:BFS 层序遍历实现(更高效)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
#include <queue>
using namespace std;
class Solution {
public:
int minDepth(TreeNode* root) {
if (root == nullptr) return 0;
queue<TreeNode*> q; // 存储每一层的节点
q.push(root);
int depth = 0; // 初始化深度
while (!q.empty()) {
depth++; // 处理当前层,深度+1
int levelSize = q.size(); // 当前层的节点数
// 遍历当前层的所有节点
for (int i = 0; i < levelSize; i++) {
TreeNode* curr = q.front();
q.pop();
// 找到第一个叶子节点,直接返回当前深度(最小深度)
if (curr->left == nullptr && curr->right == nullptr) {
return depth;
}
// 非叶子节点,将子节点加入队列
if (curr->left != nullptr) q.push(curr->left);
if (curr->right != nullptr) q.push(curr->right);
}
}
return depth; // 理论上不会走到这里,仅为语法完整性
}
};