【LeetCode】111. 二叉树的最小深度(BFS 解题套路框架,要会默写)

简介: 【LeetCode】111. 二叉树的最小深度(BFS 解题套路框架,要会默写)

一、BFS 知识点


BFS 就是广度优先 (Breadth first search)。与之对应的还有深度优先 (Depth first search)。


网上找到一篇文章,比较通俗易懂的介绍了这 2 者。


今天重点是 BFS ,用它解决比如找到从起点 start 到终点 target 的最近距离问题(黑色起点、红色终点)。


1268169-20211205210341501-832290314.png


BFS 相对 DFS 的最主要的区别是:BFS 找到的路径一定是最短的,但代价就是空间复杂度可能比 DFS 大很多


BFS 的核心思想就是把一些问题抽象成图,从一个点开始,向四周开始扩散


一般来说,我们写 BFS 算法都是用队列这种数据结构,每次将一个节点周围的所有节点加入队列。


这是框架,来自【labuladong】公众号的学习资源。这里要逐行阅读理解,并记忆。


// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
    Queue<Node> q; // 核心数据结构
    Set<Node> visited; // 避免走回头路
    q.offer(start); // 将起点加入队列
    visited.add(start);
    int step = 0; // 记录扩散的步数
    while (q not empty) {
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) {
            Node cur = q.poll();
            /* 划重点:这里判断是否到达终点 */
            if (cur is target)
                return step;
            /* 将 cur 的相邻节点加入队列 */
            for (Node x : cur.adj())
                if (x not in visited) {
                    q.offer(x);
                    visited.add(x);
                }
        }
        /* 划重点:更新步数在这里 */
        step++;
    }
}


代码里的一些方法说明:


  • q.offer(start),往队列尾部插入元素,当超出队列界限的时候,返回 false 。
  • q.poll(),获取并删除Queue中的第一个元素。
  • visited.add(start),向 set 集合里添加元素。
  • 队列 q 是 BFS 的核心数据结构。
  • cur.adj()泛指 cur 相邻的节点,比如说二维数组中,cur 上下左右四面的位置就是相邻节点。
  • visited 的主要作用是防止走回头路,大部分时候都是必须的。但是像一般的二叉树结构,没有子节点到父节点的指针,不会走回头路就不需要 visited。


二、BFS 解决二叉树的最小深度


给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。


1268169-20211205211415043-900770251.png


之前的做法:


class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        // 左右孩子都为null,返回 1
        if (root.left == null && root.right == null) {
            return 1;
        }
        int leftHeight = minDepth(root.left);
        int rightHeight = minDepth(root.right);
        // 左右孩子有一个为null
        if (leftHeight == 0 || rightHeight == 0) {
            return leftHeight + rightHeight + 1;
        }
        // 左右孩子都不为null,返回比较最短的 + 1
        return Math.min(leftHeight, rightHeight) + 1;
    }
}


使用 BFS ,套用框架:


  • 起点就是根节点
  • 终点就是最靠近根节点的那个「叶子节点」
  • 叶子节点就是两个子节点都是 null 的节点


class Solution {
    public int minDepth(TreeNode root) {
        if (root == null) {
            return 0;
        }
        Queue<TreeNode> q = new LinkedList<>();
        q.offer(root); // 将起点加入队列
        int depth = 1; // root 本身就是一层,depth 初始化为 1
        while (!q.isEmpty()) {
            // 将当前队列中的所有节点向四周扩散
            int sz = q.size();
            for (int i = 0; i < sz; i++) {
                TreeNode cur = q.poll();  // 获取并删除Queue中的第一个元素
                /* 划重点:这里判断是否到达终点 */
                if (cur.left == null && cur.right == null) {
                    return depth;
                }
                /* 将 cur 的相邻节点加入队列 */
                if (cur.left != null) {
                    q.offer(cur.left);
                }
                if (cur.right != null) {
                    q.offer(cur.right);
                }
            }
            /* 这里增加步数 */
            depth++;
        }
        return depth;
    }
}
相关文章
|
13天前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
28 6
|
4天前
|
存储 算法
二叉树进阶-学会层序遍历助你一次刷完leetcode10道题
文章深入探讨了二叉树的层序遍历方法,并展示了如何通过队列实现层序遍历的算法逻辑,同时指出掌握层序遍历技巧可以帮助解决LeetCode上的多道相关题目。
二叉树进阶-学会层序遍历助你一次刷完leetcode10道题
|
4天前
|
算法 Java
LeetCode第94题二叉树的中序遍历
文章介绍了LeetCode第94题"二叉树的中序遍历"的解法,使用递归实现了中序遍历的过程,遵循了"左根右"的遍历顺序,并提供了清晰的Java代码实现。
LeetCode第94题二叉树的中序遍历
|
13天前
|
索引 Python
【Leetcode刷题Python】从列表list中创建一颗二叉树
本文介绍了如何使用Python递归函数从列表中创建二叉树,其中每个节点的左右子节点索引分别是当前节点索引的2倍加1和2倍加2。
17 7
|
13天前
|
Python
【Leetcode刷题Python】剑指 Offer 32 - II. 从上到下打印二叉树 II
本文提供了一种Python实现方法,用于层次遍历二叉树并按层打印结果,每层节点按从左到右的顺序排列,每层打印到一行。
25 3
|
11天前
|
存储 算法 Java
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
LeetCode经典算法题:二叉树遍历(递归遍历+迭代遍历+层序遍历)以及线索二叉树java详解
31 0
|
11天前
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
23 0
|
13天前
|
Python
【Leetcode刷题Python】剑指 Offer 26. 树的子结构
这篇文章提供了解决LeetCode上"剑指Offer 26. 树的子结构"问题的Python代码实现和解析,判断一棵树B是否是另一棵树A的子结构。
28 4
|
13天前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
43 2
|
13天前
|
Python
【Leetcode刷题Python】剑指 Offer 30. 包含min函数的栈
本文提供了实现一个包含min函数的栈的Python代码,确保min、push和pop操作的时间复杂度为O(1)。
13 4