111. 二叉树的最小深度
题目:
111.二叉树的最小深度
方法一:深度优先搜索
思路及解法
首先可以想到使用深度优先搜索的方法,遍历整棵树,记录最小深度。
对于每一个非叶子节点,我们只需要分别计算其左右子树的最小叶子节点深度。这样就将一个大问题转化为了小问题,可以递归地解决该问题。
代码
int minDepth(struct TreeNode *root) {
if (root == NULL) {
return 0;
}
if (root->left == NULL && root->right == NULL) {
return 1;
}
int min_depth = INT_MAX;
if (root->left != NULL) {
min_depth = fmin(minDepth(root->left), min_depth);
}
if (root->right != NULL) {
min_depth = fmin(minDepth(root->right), min_depth);
}
return min_depth + 1;
}
补充知识:
int fmin(int a,int b); 求a,b中的最小值
int fmax(int a,int b);求a,b中的最大值
方法:
思路:
很多人写出的代码都不符合 1,2 这个测试用例,是因为没搞清楚题意
题目中说明:叶子节点是指没有子节点的节点,这句话的意思是 1 不是叶子节点
题目问的是到叶子节点的最短距离,所以所有返回结果为 1 当然不是这个结果
另外这道题的关键是搞清楚递归结束条件
叶子节点的定义是左孩子和右孩子都为 null 时叫做叶子节点
当 root 节点左右孩子都为空时,返回 1
当 root 节点左右孩子有一个为空时,返回不为空的孩子节点的深度
当 root 节点左右孩子都不为空时,返回左右孩子较小深度的节点值
第一版代码:
int minDepth(struct TreeNode *root) {
if(root == NULL)
return 0;
//这道题递归条件里分为三种情况
//1.左孩子和有孩子都为空的情况,说明到达了叶子节点,直接返回1即可
if(root->left == NULL && root->right == NULL)
return 1;
//2.如果左孩子和由孩子其中一个为空,那么需要返回比较大的那个孩子的深度
int m1 = minDepth(root->left);
int m2 = minDepth(root->right);
//这里其中一个节点为空,说明m1和m2有一个必然为0,所以可以返回m1 + m2 + 1;
if(root->left == NULL || root->right == NULL)
return m1 + m2 + 1;
//3.最后一种情况,也就是左右孩子都不为空,返回最小深度+1即可
return fmin(m1,m2) + 1;
}
代码可以进行简化,当左右孩子为空时 m1m1 和 m2m2 都为 00
可以和情况 22 进行合并,即返回 m1+m2+1m1+m2+1
简化后代码如下:
int minDepth(struct TreeNode *root) {
if(root == NULL)
return 0;
int m1 = minDepth(root->left);
int m2 = minDepth(root->right);
//1.如果左孩子和右孩子有为空的情况,直接返回m1+m2+1
//2.如果都不为空,返回较小深度+1
return root->left == NULL || root->right == NULL ? m1 + m2 + 1 : fmin(m1,m2) + 1;
}
思路:
二叉树为空树,最小深度为0;
二叉树不为空树,两子树均不为空,获取左右子树的最小深度,取最小的那个加1;
二叉树不为空树,但两子树其中之一为空,最小深度为子树不为空的最小深度加1。
代码:
#define min(A, B) ((A) < (B) ? (A) : (B))
int minDepth(struct TreeNode* root){
if (root == NULL) {
return 0;
}
int left = minDepth(root->left);
int right = minDepth(root->right);
return (left && right) ? min(left, right) + 1 : left + right + 1;
}
思路:
先判断二叉树是否为空树,然后再逐个判断左右子树是否为空
代码:
#define min(A, B) ((A) < (B) ? (A) : (B))
int minDepth(struct TreeNode* root){
if (root == NULL) {
return 0;
}
if (root->left == NULL) {
return minDepth(root->right) + 1;
} else if (root->right == NULL) {
return minDepth(root->left) + 1;
}
return min(minDepth(root->left), minDepth(root->right)) + 1;
}
比较好的解释:
四版DFS-一版BFS
好的思路解析
这道题要找出给定二叉树的最小深度,还是DFS来做,其中有一些细节的地方,特殊的测试用例需要注意
在这个递归过程中,我们需要做以下判断递归结束条件:
如果当前节点是NULL,返回0,因为没有节点了不再有深度增加
如果当前节点左右指针都为NULL,说明是叶节点,返回1,深度加一
如果当前左右指针有一个为NULL,那么需要注意,因为为NULL的那一边不算有叶子节点!所以深度只能算不是NULL的那一边
比如测试用例[1,2],根节点1只有左子为2,返回的深度是1+左子节点返回的1=2,而不是1+右子节点返回的0=0。
剩下的是普通继续递归的情况,也就是左子和右子中较小的一方深度+1
根据执行出错的测试用例才能够知道代码漏洞呢,自己还是考虑不够周全!