LeetCode-111.[二叉树的最小深度]

16 阅读3分钟

题目描述

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明: 叶子节点是指没有子节点的节点。

示例 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,递归实现)

这是最直观的递归思路,核心是分情况处理左右子树:

  1. 边界条件:如果根节点为空,返回 0(空树深度为 0)。

  2. 递归处理左右子树:

    • 若左子树为空、右子树非空:最小深度 = 右子树的最小深度 + 1(当前节点不是叶子,需依赖右子树)。
    • 若右子树为空、左子树非空:最小深度 = 左子树的最小深度 + 1。
    • 若左右子树都非空:最小深度 = min (左子树最小深度,右子树最小深度) + 1(取更小的子树深度,加当前节点)。

方法 2:广度优先搜索(BFS,层序遍历)

这是更高效的方法(找到第一个叶子节点就直接返回,无需遍历整棵树):

  1. 边界条件:根节点为空,返回 0。

  2. 用队列存储每一层的节点,初始化深度为 0。

  3. 逐层遍历节点:

    • 每处理一层,深度 + 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; // 理论上不会走到这里,仅为语法完整性
    }
};