Java 深度优先搜索 and 广度优先搜索的算法原理和代码展示

发布时间 2023-10-14 18:09:10作者: 修炼诗人

111. 二叉树的最小深度

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

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

方法1:深度优先搜索

原理:深度优先搜索(Depth First Search)是一种遍历图的算法,它从图中的某个顶点出发,沿着一条路径不断向下探索,直到无法继续深入为止,然后回溯到上一个顶点,继续探索其他路径,直到所有顶点都被访问过为止, 所有的顶点都被压入中。栈:先进后出。

思路:使用深度优先搜索,遍历整棵树,记录最小的深度。对于每一个非叶子节点,分别计算其左右叶子结点的最小叶子结点深度。通过递归的方式解决该问题。但递归在运行时,值的变化很难把握。

   public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        // 最小深度
        int min_depth = Integer.MAX_VALUE;
        // 左子树节点
        if(root.left != null){
            min_depth = Math.min(minDepth(root.left), min_depth);
        } 
        // 右子树节点
        if(root.right != null){
            min_depth = Math.min(minDepth(root.right), min_depth);
        } 
        return min_depth + 1;
}

时间复杂度为O(N),因为二叉树中,每一个子节点都被访问过。平均空间复杂度O(logN)。  

方法2:广度优先搜索

原理:广度优先搜索(Breadth First Search)是一种遍历图的算法,它从图中的某个顶点出发,沿着一条路径不断向下探索,直到无法继续深入为止,然后回溯到上一个顶点,继续探索其他路径,直到所有顶点都被访问过为止, 所有的顶点都被压入队列中。队列:先进先出。

思路:使用广度优先搜索,当我们找到一个叶子节点时,直接返回这个叶子节点的深度。广度优先搜索的性质保证了最先搜索到的叶子节点的深度一定最小。

class QueueNode{
        // 定义属性
        TreeNode node;
        int depth;
        // 构造函数
        public QueueNode(TreeNode node,int depth){
            this.node = node;
            this.depth = depth;
        }
    }
    public int minDepth(TreeNode root) {
        if(root == null){
            return 0;
        }
        Queue<QueueNode> queue1 = new LinkedList<QueueNode>();
        queue1.offer(new QueueNode(root,1));// 先将第一个根节点放入队列中
        while(!queue1.isEmpty()){
            // 弹出首个元素
            QueueNode nodedepth = queue1.poll();
            TreeNode node = nodedepth.node;
            int depth = nodedepth.depth;
            if (node.left == null && node.right == null) {
                // 最终的出口一定在这里
                return depth;
            }
            // 左子树节点
            if(node.left != null){
                // 将节点放入队列中 depth = depth + 1
                queue1.offer(new QueueNode(node.left,depth + 1));
            } 
            // 右子树节点
            if(node.right != null){
                // 将节点放入队列中 depth = depth + 1
                queue1.offer(new QueueNode(node.right,depth + 1));
            } 
        }
        return 0;
    }

 时间复杂度为O(N),因为二叉树中,每一个子节点都被访问过。平均空间复杂度O(N)。