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)。