如何优雅地求二叉树的最小深度

102 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情 >>

如何求二叉树的最小深度

前置知识准备

在这之前,我们有一起学习过如何去求二叉树的最大深度,如果有对如何求二叉树的最大深度不熟悉的朋友可以先复习一下:【数据结构】二叉树的最大深度 - 掘金 (juejin.cn)

虽然求最小深度和求最大深度只有一字之差,但是真正实现起来他们还是有一定区别的,就比如说我们不能把求最大深度时的Math.max() 直接改成Math.min就完事了,其实这样是无法通过的,还有一些细节需要处理;那么接下来咱们就直接开始学习一下如何优雅地去求解二叉树的最小深度。

另外,还有一点我们需要明确的,那就是——二叉树的最小深度到底指的是什么?

这里的二叉树的最小深度指的是从根节点到叶子结点最短的距离

如何求解二叉树的最小深度

其实有了前面求二叉树的最大深度的经验,相信各位朋友在这里很快就有想法了。

使用递归法:

递归终止条件:

if (root == null) {
	return 0;
}
if (root.left == null && root.right == null) {
	return 1;
}

注意这里递归终止条件并不是只有 if (root == null) 一个,它还应包括 if (root.left == null && root.right == null) 。

为什么还需要后面那个判断呢?在同样方法求最大深度的时候,明明不需要这个的啊?

其实这个也正是这种方法在求最大深度和最小深度之间的区别所在

这么说吧,这个条件是为了防止后面空节点也进入递归,如果这样的话,统计量就会被改变了 (如何这里有疑惑的话,不用着急,继续往下看就明白了的)

统计变量:

其中min统计的就是二叉树的最小深度,left 和 right 就是在递归的过程中临时记录当前深度

int min = Integer.MAX_VALUE;
int right = Integer.MAX_VALUE;
int left = Integer.MAX_VALUE;

单层递归逻辑:

不断递归处理子节点,注意空节点是不处理的

if (root.left != null) {
	 left = Math.min(min, minDepth(root.left));
}
if (root.right != null) {
	 right = Math.min(min, minDepth(root.right));
}

说到了这里,咱们回过头来,再看一看,就很容易可以写出完整的求解代码了:

public int minDepth(TreeNode root) {
	if (root == null) {
		return 0;
	}
	if (root.left == null && root.right == null) {
		return 1;
	}
	int min = Integer.MAX_VALUE;
	int right = Integer.MAX_VALUE;
	int left = Integer.MAX_VALUE;
	if (root.left != null) {
		 left = Math.min(min, minDepth(root.left));
	}
	if (root.right != null) {
		 right = Math.min(min, minDepth(root.right));
	}
	return Math.min(left, right) + 1;
}

总结:

其实这里求二叉树的最小深度和之前求最大深度的想法很是相似的 都是从下往上不断返回统计、 但是这里有一些不同,其实最主要的是一个初始化和空值要不要递归的问题

在求树的最大深度的时候:

其实在这种情况下,初不初始化都是没问题的,
因为最大深度求的是最大值,而树的最小深度是 0 ,所以说 0 就是最小值了

在求树的最小深度的时候:

 这里所指的最小深度并不是树的左右孩子最小 + 1
 因为当其中一个孩子为空的时候,最小值就会一直为 0 ,而另外一个孩子不为空,所以树的最小深度不会是 0
 这里需要的是不断取最小值,所以需要将统计的变量初始化为最大值
 至于为什么不能递归空值,那是因为如何递归空值的话,统计变量就变成 0 了,0 再和其他任何深度比都是 0 了
 换句话说,求树的最小深度就是在不断统计不为 0 的深度的最小值