【算法题解】34. 二叉树的最小深度

这篇具有很好参考价值的文章主要介绍了【算法题解】34. 二叉树的最小深度。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这是一道 简单

https://leetcode.cn/problems/minimum-depth-of-binary-tree/

题目

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

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

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

示例 1:

【算法题解】34. 二叉树的最小深度

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

示例 2:

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

提示:

  • 树中节点数的范围在 [ 0 , 1 0 5 ] [0, 10^5] [0,105]
  • − 1000 < = N o d e . v a l < = 1000 -1000 <= Node.val <= 1000 1000<=Node.val<=1000

简单递归解法

这道题目和 二叉树的最大深度 一样,都可以使用递归解法。

求解公式为: 二叉树的最小深度 = M i n Min Min(左子树的最小深度,右子树的最小深度) + 1

但是需要注意的是,只有左子树和右子树都不为空的时候才能使用上述公式求解。

如果左子树为空,那么二叉树的最小深度 = 右子树的最小深度 + 1。如下图所示:
【算法题解】34. 二叉树的最小深度
同样的如果右子树为空,那么二叉树的最小深度 = 左子树的最小深度 + 1

极端情况下会退化成链表,如下图所示:
【算法题解】34. 二叉树的最小深度

Java 代码实现
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }

        // 没有子树
        if(root.left == null && root.right == null){
            return 1;
        }

        int leftDepth = minDepth(root.left);
        int rightDepth = minDepth(root.right);

        if(leftDepth == 0){
            return rightDepth + 1;
        }else if(rightDepth == 0){
            return leftDepth + 1;
        }else {
            return Math.min(leftDepth, rightDepth) + 1;
        }
        
    }
}
Go 代码实现
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func minDepth(root *TreeNode) int {

    if root == nil {
        return 0
    }

    if root.Left == nil && root.Right == nil {
        return 1
    }

    leftMin := minDepth(root.Left)
    rightMin := minDepth(root.Right)

    if root.Left == nil {
        return rightMin + 1
    }else if root.Right == nil {
        return leftMin + 1
    }else{
        return min(leftMin, rightMin) + 1
    }

}

func min(a int, b int) int {
    if a < b {
        return a
    }else {
        return b
    }
}
复杂度分析
  • 时间复杂度 O ( N ) O(N) O(N)N 为二叉树中节点的个数,每个节点都需要计算一次,总共 N 次。
  • 空间复杂度 O ( N ) O(N) O(N)N 为二叉树中节点的个数,空间复杂度为调用栈的深度,最多为 N ,即二叉树退化成链表的时候。

DFS

相较于上一步的简单递归解法,深度优先遍历的优点是可以进行剪枝,如下图所示:
【算法题解】34. 二叉树的最小深度
root节点3节点9 的深度是2,那么在遍历到 节点20 的时候深度已经达到2了,后面就无需再遍历,可以直接返回了。

另外需要注意的是边界条件和还原现场:

  • 边界条件:碰到叶子结点时计算一次最小深度,并返回。
  • 还原现场depth--,每次回退到上一层的时候深度跟着要减一。
Java 代码实现
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    private int depth = 1;
    private int ans = Integer.MAX_VALUE;
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        dfs(root);
        return ans; 
    }

    private void dfs(TreeNode node){

        // 剪枝
        if(depth >= ans){
            return;
        }

        // 边界条件,碰到叶子结点计算一次最小深度
        if(node.left == null && node.right == null){
            ans = Math.min(ans, depth);
            return;
        }

        depth++;

        // 遍历左子树
        if(node.left != null){
            dfs(node.left);
        }
        
        // 遍历右子树
        if(node.right != null){
            dfs(node.right);
        }
        
        // 还原现场
        depth--;
        
    }
}
Go 代码实现
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */

var (
    depth int
    ans int
)
func minDepth(root *TreeNode) int {

    if root == nil {
        return 0
    }

    depth = 1
    ans = 2 << 32 - 1

    dfs(root)
    
    return ans

}

func dfs(node *TreeNode) {
    // 剪枝
    if depth >= ans {
        return
    }

    // 边界条件
    if node.Left == nil && node.Right == nil {
        ans = min(ans, depth)
        return
    }

    depth++
    if(node.Left != nil){
        dfs(node.Left)
    }
    if(node.Right != nil){
        dfs(node.Right)
    }
    // 还原现场
    depth--
}

func min(a int, b int) int {
    if a < b {
        return a
    }else {
        return b
    }
}
复杂度分析
  • 时间复杂度 O ( N ) O(N) O(N)N 为二叉树中的节点个数,最差的情况是每个节点都需要遍历一次,总计 N 次。
  • 空间复杂度 O ( N ) O(N) O(N)N 为二叉树中节点的个数,空间复杂度为调用栈的深度,最多为 N 层。

BFS

广度优先遍历,一层一层的逐层遍历,遇到的第一个叶子结点的深度就是最小深度。

以下图为例,当遍历到 节点9 的时候,就可以直接返回了。
【算法题解】34. 二叉树的最小深度

Java 代码实现
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList<>();
        int depth = 1;
        queue.offer(root);
        while(!queue.isEmpty()){
            // 同一层节点个数
            int len = queue.size();

            // 将同一层节点全部取出,并将下一层节点入队
            for(int i = 0; i < len; i++){
                TreeNode node = queue.poll();
                // 第一次遇到叶子结点,就是最小深度
                if(node.left == null && node.right == null){
                    return depth;
                }
                // 左子树入队
                TreeNode leftNode = node.left;
                if(leftNode != null){
                    queue.offer(leftNode);
                }

                // 右子树入队
                TreeNode rightNode = node.right;
                if(rightNode != null){
                    queue.offer(rightNode);
                }
            }
            // 同一层节点全部取出后,深度加一
            depth++;
        }
        return depth; 
    }

}
Go 代码实现
/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */


func minDepth(root *TreeNode) int {

    if root == nil {
        return 0
    }

    queue := []*TreeNode{root}
    depth := 1

    for len(queue) > 0 {
        // 同一层节点个数
        len := len(queue)
        
        // 将同一层节点全部取出,并将下一层节点入队
        for i := 0; i < len; i++ {
            node := queue[0]
            queue = queue[1:]
            // 第一次遇到叶子结点,就是最小深度
            if node.Left == nil && node.Right == nil {
                return depth
            }
            // 左子树入队
            if node.Left != nil {
                queue = append(queue, node.Left)
            }
            // 右子树入队
            if node.Right != nil {
                queue = append(queue, node.Right)
            }
        }
        // 同一层节点全部取出后,深度加一
        depth++
    }


    return depth
}
复杂度分析
  • 时间复杂度 O ( N ) O(N) O(N)N 为二叉树中节点的个数,最坏的情况下需要遍历每一个节点。
  • 空间复杂度 O ( N ) O(N) O(N)N 为二叉树中节点的个数,空间复杂度主要取决于队列的大小,最差的情况就是放 N 个元素。

总结

简单递归解法 的思路最为简单,但是需要计算所有节点,所以效率上不是最好的。

DFSBFS 虽然时间复杂度上也都是 O ( N ) O(N) O(N),但这是在最坏的情况下得到的,通常都不需要遍历所有节点,所以效率要高一些。

因为 BFSDFS 所需要遍历的节点数会更少一些,所以个人觉得求最小深度(最短路径)的题目使用 BFS 更为合适一些。文章来源地址https://www.toymoban.com/news/detail-472613.html

到了这里,关于【算法题解】34. 二叉树的最小深度的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • day16 二叉树的最大深度 n叉树的最大深度 二叉树的最小深度 完全二叉树的节点数

    题目链接:104 二叉树的最大深度 题意 二叉树的根节点是root,返回其最大深度(从根节点到最远叶子节点的最长路径上的节点数) 递归 根节点的的高度就是二叉树的最大深度  所以使用后序遍历求最大高度的方式求出最大深度 递归三部曲 1)确定递归函数的参数和返回值

    2024年02月02日
    浏览(33)
  • 第十五天|104.二叉树的最大深度、111.二叉树的最小深度、 222.完全二叉树的节点个数

    104.二叉树的最大深度 题目链接:104. 二叉树的最大深度 - 力扣(LeetCode) 111.二叉树的最小深度 题目链接:111. 二叉树的最小深度 - 力扣(LeetCode) 222.完全二叉树的节点个数 题目链接:222. 完全二叉树的节点个数 - 力扣(LeetCode)

    2024年02月11日
    浏览(24)
  • 【深度优先】【广度优先】Leetcode 104 二叉树的最大深度 Leetcode 111 二叉树的最小深度 Leetcode 110 平衡二叉树

    二叉树节点的深度: 指从根节点到该节点的最长简单路径边的条数或者节点数 (取决于深度从0开始还是从1开始) 二叉树节点的高度: 指从该节点到叶子节点的最长简单路径边的条数后者节点数 (取决于高度从0开始还是从1开始) 【前序求的是深度,后序求的是高度】 -

    2024年02月19日
    浏览(39)
  • 每日一练:LeeCode-111. 二叉树的最小深度【二叉树】

    本文是力扣LeeCode-111. 二叉树的最小深度 学习与理解过程,本文仅做学习之用,对本题感兴趣的小伙伴可以出门左拐LeeCode。 给定一个 二叉树 ,找出其 最小深度 。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量 。 说明: 叶子节点是指没有子节点的节点 。 示

    2024年02月02日
    浏览(25)
  • 求二叉树的最小深度(深度优先和广度优先)

    自己建一个二叉树,然后分别使用深度优先和广度优先找到二叉树的最小深度。 代码中有注释哦~

    2024年02月12日
    浏览(29)
  • 代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数

    以下题解的更详细思路来自于:代码随想录 (programmercarl.com) 二叉树的高度与深度 这里先补充一下二叉树深度和高度的概念 高度:二叉树中任意一个节点到叶子结点的距离 深度:二叉树中任意一个节点到根节点的距离 下面给出一个图便于理解 获取高度与深度的遍历方式 高度:后

    2024年02月08日
    浏览(30)
  • leetcode111. 二叉树的最小深度(java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/minimum-depth-of-binary-tree 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。 示例1: 输入:root = [3,9,20,null,null,15,7] 输出:2 示例2: 输入:

    2024年02月09日
    浏览(23)
  • LeetCode第111题 - 二叉树的最小深度

    题目 解答 方案一 方案二 要点 方案一不够优雅,全量计算了所有节点的路径长度,同时复用树节点中的val字段来保存数据。 依据树的递归定义,符合要求的节点要么在左子树,要么在右子树,因此可以利用这个特点,递归的针对树的每个节点的左、右子树,分别求解其最小

    2024年01月22日
    浏览(27)
  • 二叉树的最大深度和最小深度(两种方法:递归+迭代)

    二叉树的最大深度:   二叉树的最小深度: 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明: 叶子节点是指没有子节点的节点。  输入:root = [3,9,20,null,null,15,7] 输出:2  

    2024年02月15日
    浏览(24)
  • leetcode做题笔记111. 二叉树的最小深度

    给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明: 叶子节点是指没有子节点的节点。 本题与求二叉树最大深度的题很像,先判断根节点,再递归看左右子树最小值返回最小深度,由于根节点若在的话至少有一个节点所

    2024年02月11日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包