持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第15天,点击查看活动详情
题目
题目链接:力扣111:二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6] 输出:5
提示:
- -树中节点数的范围在 [0, 10^5] 内
- --1000 <=
Node.val<= 1000
解题思路
👉迭代法
这题我最先想到的思路是昨天的层次遍历。
可以用队列对二叉树进行层次遍历,每次遍历都是用当前层次的节点,将下一层的节点放入队列中,每次放入前都要考虑该节点是否存在左右孩子,存在就放入队列,不存在则不放。可以在这里加一个判断条件,当该节点没有孩子时,就是叶子节点,即找到了最小深度。
如图,当层次遍历到第二层时,会找到9这个节点是叶子节点,此时可以直接返回,该层次数即是最小深度。
👉递归法
还有一种思路是递归法。
求最大深度时,我用的是这种方法,所以我想到了这两题是雷同的。递归法和二叉树的后序遍历相似,每递归一次就要加一,因为和层次遍历一样,每递归一次就是进入下一层。当递归结束后比较左右子树的深度,取值小的那个。
这里有个要注意的是如果节点只有一个孩子时,要取有孩子的那边的值。
如图,如果此时节点9需要取左孩子的深度值。
代码(C++)
迭代
class Solution {
public:
int minDepth(TreeNode* root) {
queue<TreeNode *> queue;
queue.push(root);
int f = 0;
if (!root)
return 0;
while (!queue.empty()) {
TreeNode *t;
int i = queue.size();
f ++; //记录层次
for (int j = 0; j < i ; ++ j) {
t = queue.front();
queue.pop();
if (!t->left && !t->right) { //遇到第一个叶子节点
return f;
}
if (t->left) {
queue.push(t->left);
}
if (t->right) {
queue.push(t->right);
}
}
}
return f;
}
};
递归
class Solution {
public:
int minDepth(TreeNode* root) {
if (!root)
return 0;
int l = 0, r = 0;
l += minDepth(root->left);
r += minDepth(root->right);
if (l && !r) //节点的右孩子为空,取左孩子的值
return l + 1;
else if (!l && r) //左孩子为空,取右孩子的值
return r + 1;
if (l > r)
return r + 1;
else
return l + 1;
}
};
拓展(求最大深度)
int Treedepth(BT *T)
{
int ldep,rdep;
if(T==NULL)
return 0;
else
{
ldep=Treedepth(T->lchild);
rdep=Treedepth(T->rchild);
if(ldep>rdep)
return ldep+1;
else
return rdep+1;
}
}
总结
这题的递归法,主要是存在一个孩子为空的情况不好想到。其他的不算太难想到。
这题和求最大深度的问题几乎一样,可以多了解了解。