Leetcode 111. 二叉树的最小深度

187 阅读1分钟

Leetcode 111. 二叉树的最小深度

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情

1、题目📑

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

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

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

实例1

img

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

输出:2

实例2

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

输出:5

提示

  • 树中节点数的范围在 [0, 105]
  • -1000 <= Node.val <= 1000

2、思路🧠

方法一:二叉树的递归套路

  1. 明确结束递归的条件
    • 节点头为空时,结束递归调用
  2. 列出所有的可能情况,头节点不为空,
    • 左树、右树均为空,返回头节点的根节点数量,即 1
    • 左树为空,右树不为空,返回递归右树,返回 节点数+1
    • 右树为空,左树不为空,返回递归左树,返回 节点数+1
    • 左树、右树均不为空,返回数量小的结点数进行再次递归,将结点数+1

废话少说~~~~~上代码!

3、代码👨‍💻

第一次commit AC

/**
 * 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;
        if(root.left == null) return minDepth(root.right) + 1;
        if(root.right == null) return minDepth(root.left) + 1;
        if(root.left != null && root.right != null) 
            return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
        return 1;
    }
}

化简

/**
 * 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;
        //左右节点任何一个为空
        if(root.left == null || root.right == null) 
            return minDepth(root.left) + minDepth(root.right) + 1;
        //最后一种情况,左右节点都不为空
        return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
    }
}

再次化简

/**
 * 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;
        // //左右节点任何一个为空
        // if(root.left == null || root.right == null) 
        //     return minDepth(root.left) + minDepth(root.right) + 1;
        // //最后一种情况,左右节点都不为空
        // return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
       int minleft = minDepth(root.left);
       int minright = minDepth(root.right);
        //将第一种 和 第二种 情况进行合并处理
        return root.left == null || root.right == null ? minleft + minright + 1 : Math.min(minleft, minright) + 1;
    }
}

时间复杂度:O(N) N 为树的节点数;每个节点访问一次

空间复杂度:O(log N)

image-20220414103825257

4、总结

该题目的是对树结构的理解与遍历,需要掌握先序、中序、后序的基本概念以及遍历。并且还要了解树的递归操作,以及每一步的具体流程。

树的先序、中序、后序模板:

package com.cz.Tree;

import java.util.Stack;

/**
 * @ProjectName: Data_structure
 * @Package: com.cz.Tree
 * @ClassName: UnRecursiveTraversalTree
 * @Author: 张晟睿
 * @Date: 2022/3/20 16:06
 * @Version: 1.0
 */
public class UnRecursiveTraversalTree {
    public static void main(String[] args) {
        Node1 head = new Node1(1);
        head.left = new Node1(2);
        head.right = new Node1(3);
        head.left.left = new Node1(4);
        head.left.right = new Node1(5);
        head.right.left = new Node1(6);
        head.right.right = new Node1(7);

        pre(head);
        System.out.println("========");
        middle(head);
        System.out.println("========");
        post(head);
        System.out.println("========");
    }
    public static class Node1 {
        public int value;
        public Node1 left;
        public Node1 right;

        public Node1(int val) {
            value = val;
        }
    }

    public static void pre(Node1 head) {
        System.out.println("先序遍历:");
        Stack<Node1> s = new Stack<>();
        if(head != null) {
            s.push(head);
            while(!s.isEmpty()) {
               Node1 node = s.pop();
                System.out.print(node.value + " ");
                if(node.right != null) s.push(node.right);
                if(node.left != null) s.push(node.left);
            }
        }
        System.out.println();
    }

    public static void middle(Node1 head){
        System.out.println("中序遍历:");
        if (head != null) {
            Stack<Node1> s = new Stack<>();
            while(!s.isEmpty() || head != null) {
                //步骤1:如果头结点不为空的话,一直向左边执行
                if (head != null) {
                    s.push(head);
                    head = head.left;
                }else {//根节点打印后,来到右树,继续执行步骤1
                    head = s.pop();
                    System.out.print(head.value + " ");
                    head = head.right;
                }
            }
            System.out.println();
        }
    }

    public static void post(Node1 head){
        System.out.println("后序遍历:");
        if(head != null) {
            Stack<Node1> s = new Stack<>();
            s.push(head);
            Node1 c = null; //指向栈顶的某个元素的位置
            while(!s.isEmpty()) {
                c = s.peek();
                //判断c左孩子 是否已经处理过
                if(c.left != null && head != c.left && head != c.right) {
                    s.push(c.left);
                    //判断c右孩子 是否已经处理过
                }else if(c.right != null && head != c.right) {
                    s.push(c.right);
                }else {
                    System.out.print(s.pop().value+" ");
                    head = c;   //head用来记录上次打印的内容
                }
            }
            System.out.println();
        }
    }
}

❤️‍来自专栏《LeetCode基础算法题》欢迎订阅❤️‍

厂长写博客目的初衷很简单,希望大家在学习的过程中少走弯路,多学一些东西,对自己有帮助的留下你的赞赞👍或者关注➕都是对我最大的支持,你的关注和点赞给厂长每天更文的动力。

对文章其中一部分不理解,都可以评论区回复我,我们来一起讨论,共同学习,一起进步!

原题链接:111. 二叉树的最小深度 - 力扣(LeetCode) (leetcode-cn.com)