一、题目描述
Given a binary tree, find its minimum depth.
The minimum depth is the number of nodes along the shortest path
from the root node down to the nearest leaf node.
Note: A leaf is a node with no children.
Given binary tree [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
return its minimum depth = 2.
二、题解
方法一:层序遍历(Queue)
不一定一上来就用递归。怎么简单怎么来。所以我将处于同一深度的节点一起处理,判断其中是否有叶子节点,有叶子结点,那么最小深度就是当叶子结点层的深度。
public int minDepth1(TreeNode root) {
if (root == null) return 0;
int depth = 1;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
int level_size = queue.size();
for (int i = 0; i < level_size; i++) {
TreeNode node = queue.poll();
if (node.left == null && node.right == null) return depth;
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
depth++;
}
return -1;
}
复杂度分析
- 时间复杂度: ,按照树的层次一层一层的访问完所有节点。
- 空间复杂度: ,
方法二:dfs 迭代
参考了别人的做法:
- 每次弹出栈顶元素,并将它的孩子节点压入栈中。
- 遇到叶子节点时才更新最小深度 minDepth。
- 需要增加一个类 pair,用来记录每个结点的深度。
public int minDepth2(TreeNode root) {
if (root == null) return 0;
int minDepth = 0x7fffffff;
Stack<Pair> stack = new Stack<>();
stack.push(new Pair(root, 1));
while (!stack.isEmpty()) {
TreeNode node = stack.peek().node;
int depth = stack.peek().depth;
stack.pop();
if (node.left == null && node.right == null) minDepth = Math.min(minDepth, depth);
if (node.left != null) stack.push(new Pair(node.left, depth + 1));
if (node.right != null) stack.push(new Pair(node.right, depth + 1));
}
return minDepth;
}
class Pair {
TreeNode node;
int depth;
public Pair(TreeNode _node, int _depth) {
node = _node;
depth = _depth;
}
}
复杂度分析
- 时间复杂度: ,
- 空间复杂度: ,
方法三:递归
递归看起来不是特别难,和二叉树最大深度类似,只不过这一题需要找到最近的叶子结点。一开始我把代码写成这样了:
public int minDepth(TreeNode root) {
if (root == null) return 0;
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}
提交后却没有答对,原因是当 root = [1,2]
时,返回的竟然是 1。因为我取的是左右子树的最小深度,但这里只要结点 2 是叶子结点。
1
/
2
思路
还是根据递归三部曲:
- 结束时机:遇到叶子结点。
- 返回值:
- 遇到叶子结点返回高度 1。
- 本层递归的责任:
- 找到不空的左右子结点,并寻找他们之间的最小值。
算法
- 遇到叶子结点返回高度 1;
- 左子树空,则返回当前结点高度 + 右子树最小高度;
- 右子树空,则返回当前结点高度 + 左子树最小高度;
- 左右子树都不空,返回二者的最小高度。
- 左右子树都空,返回当前高度 1。
第一版代码:
private int findDepth(TreeNode root) {
//叶子结点返回高度1
if (root.left == null && root.right == null) return 1;
//左子树空,但右子树可能不空
if (root.left == null) return findDepth(root.right) + 1;
//右子树空,但左子树可能不空
if (root.right == null) return findDepth(root.left) + 1;
//左右子树都不空,则返回小高度小的
return Math.min(findDepth(root.left), findDepth(root.right)) + 1;
}
public int minDepth1(TreeNode root) {
if (root == null) return 0;
//左子树空,但右子树可能不空
if (root.left == null) return minDepth(root.right) + 1;
//右子树空,但左子树可能不空
if (root.right == null) return minDepth(root.left) + 1;
//左右子树都不空,则返回小高度小的/如果都空则返回当前层高度1
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}
复杂度分析
- 时间复杂度: ,
- 空间复杂度: ,