求给定二叉树的最小深度,最小深度是指树的根结点到最近叶子结点的最短路径上结点的数量
首先要明白递归是实现该算法的最优方式,其实对于该算法有一个比较整体上的认识:要想得到最小深度,那么就可以先获取到左右子树的最小深度,然后加一,那么要想要想获取到左(右)子树的最小深度,那么就还要获取到该子树的左右子树的最小深度再加一,到这里我们就已经形成了一个递归的雏形。
我们设计的这个递归方法,往大来看就是获取根节点左右子树的最小深度(往大来看的深层含义就是最外层递归的最后大的返回值!),往小来看就是获取最小子树的深度(往小来看的深层含义就是最小子树的深度无非就是0或者1)。
数据定义:
/**
* Definition for binary tree
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
我们先来设计最外层run(简称一号run):假设该二叉树最大深度为n,一号run直接获得到n-1阶左右子树的最小深度,进行比较,返回结果。
其实这里我们已经把二号run的调用已经写出来了,因为递归肯定是自己调用自己,这个二号run的作用是什么呢?就是获得n-2阶子树的最小深度。但是在递归算法的设计中,最重要的就是考虑一号和n号run的功能
public class Solution {
public int run(TreeNode root) {
int left = run(root.left);
int right = run(root.right);
return 1+Math.min(left,right);
}
}
n号run:这个功能就是最小的功能,这个方法递归到最小就是获取最小子树的深度,而最小子树的根节点要不然就是空,要不然就是叶子节点。
不仅如此,其实还有一种情况,那就是只有左子树或者右子树的情况,这种情况就要进行判断,如果只有左子树,那就返回左子树的最小深度,如果只有右子树,那就返回右子树的最小深度。
public class Solution {
public int run(TreeNode root) {
//如果根节点为空 深度就为0
if(root == null ){
return 0;
}
//如果为叶子节点 深度就为1
if(root.left == null && root.right == null){
return 1;
}
//如果左子树为空 返回右子树的最小深度
if(root.left == null)
return run(root.right)+1;
//如果右子树为空 返回左子树的最小深度
if(root.right == null)
return run(root.left)+1;
//如果左右都不为空 那么就分别计算左右子树的深度,取最小值
int left = run(root.left);
int right = run(root.right);
return 1+Math.min(left,right);
}
}
其实我对于递归还不是很熟,通过这一道题,让我对递归的设计有了一定的新认识,我们基本只要考虑一号run和n号run的功能设计实现,中间的2号…n-1号run我们可以不用太详细的去认识,反而会增加自己的思路混淆!