代码随想录算法训练营第十六天 | 104.二叉树的最大深度,111.二叉树的最小深度,222.完全二叉树的节点个数 [二叉树篇]

代码随想录算法训练营第十六|Leetcode104 二叉树最大深度 、Leetcode111 二叉树最小深度、Leetcode222 完全二叉树节点个数 输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]假如左结点存在,则深度加一,然后向左孩子递归,每结束一次左孩子的递归需要深度减一,才能对右孩子进行递归,最后返回最大值即可。函数分别获取左右子树的高度,而对于二叉树的最大高度则是取两者的最大值随后加上根结点的一层即可。对于最大深度的解决,使用前序和后序遍历都可以,因为返回的都是根节点到叶子节点的最大距离。 阅读详情

LeetCode 104.二叉树的最大深度

题目链接:104.二叉树的最大深度
文章讲解:代码随想录#104.二叉树的最大深度
视频讲解:104.二叉树的最大深度

题目描述

给定一个二叉树 root ,返回其最大深度
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例1
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:3

示例2

输入:root = [1,null,2]
输出:2

提示

  • 树中节点的数量在 [0, 104] 区间内。
  • -100 <= Node.val <= 100

思路

什么是二叉树节点的高度?么是二叉树节点的深度?

  • 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
  • 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
    使用前序求的就是深度,使用后序求的是高度
    根节点的高度就是二叉树的最大深度,所以可以通过后序遍历来求二叉树的最大深度。

递归后序遍历参考代码

#define MAX(a, b) (a) > (b) ? (a) : (b)
// 使用后序遍历计算二叉树的高度,二叉树的最大深度也就是根节点到叶子节点的高度
int treeDepth(struct TreeNode *node)
{
    if (node == NULL) {
        return 0;
    }
    int lDepth = treeDepth(node->left); // 左
    int rDepth = treeDepth(node->right); // 右
    int depth = MAX(lDepth, rDepth); // 中
    return depth + 1;

}
int maxDepth(struct TreeNode* root) {
    return treeDepth(root);
}

递归前序遍历参考代码

int res;

// 使用前序遍历计算二叉树的最大深度,必须需要一个变量来记录当前遍历的depth
void treeDepth(struct TreeNode *node, int depth)
{
    res = res > depth ? res : depth;  // 中

    if (node->left == NULL && node->right == NULL) {
        return ;
    }

    if (node->left != NULL) { // 左
        depth++;
        treeDepth(node->left, depth);
        depth--; // 回溯
    }

    if (node->right != NULL) { // 右
        depth++;
        treeDepth(node->right, depth);
        depth--; // 回溯
    }
    return;
}


int maxDepth(struct TreeNode* root) {
    res = 0;
    if (root == NULL) {
        return res;
    }

    treeDepth(root, 1);
    return res;
}

总结

  1. 递归相对简单一些,后面有时间了深度用层序遍历解决这道题

LeetCode 111.二叉树的最小深度

题目链接:111.二叉树的最小深度
文章讲解:代码随想录#111.二叉树的最小深度
视频讲解:LeetCode:111.二叉树的最小深度

题目描述

给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。

示例1
在这里插入图片描述

输入:root = [3,9,20,null,null,15,7]
输出:2

示例2

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

提示

  • 树中节点数的范围在 [0, 105] 内
  • -1000 <= Node.val <= 1000

思路

这道题关键点是要计算从根节点到最近叶子节点的最短路径上的节点数量。
需要注意的是如果左子树为空,右子树不为空,则最小深度为1+右子树的深度。同样,如果右子树为空,左子树不为空,则最小深度为1+左子树的深度。

参考代码

int minDepth(struct TreeNode* root) {
    if (root == NULL) {
        return 0;
    }

    int lDepth = minDepth(root->left); // 左
    int rDepth = minDepth(root->right); // 右

    if (root->left == NULL && root->right != NULL) { // 处理中节点
        return 1 + rDepth;
    }
    if (root->left != NULL && root->right == NULL) {
        return 1 + lDepth;
    }
    int depth = lDepth > rDepth ? rDepth : lDepth; // 中
    return 1 + depth;
}

LeetCode 222.完全二叉树的节点个数

题目链接:222.完全二叉树的节点个数
文章讲解:代码随想录#222.完全二叉树的节点个数
视频讲解:要理解普通二叉树和完全二叉树的区别! | LeetCode:222.完全二叉树节点的数量

题目描述

给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。

示例1
在这里插入图片描述

输入:root = [1,2,3,4,5,6]
输出:6

示例2

输入:root = []
输出:0

示例 3

root = [1]
1

提示

  • 树中节点的数目范围是[0, 5 * 10^4]
  • 0 <= Node.val <= 5 * 10^4
  • 题目数据保证输入的树是 完全二叉树

思路

第一反应就是深度遍历或层序遍历所有的节点,时间复杂度为O(n)。
但这不是最优解,理解完全二叉树的特点后,会有更好的解决方案。
在完全二叉树中,除了最底层节点可能没有填充满以外,其余层的是一个满二叉树,而且最底层的节点都集中在最左边。
如果最底层为n层,则该层包含的节点数为[1, 2^(n-1)],除最底层以外的节点数为2^(n-1)-1。
对于一个完全二叉树,分别递归左孩子和右孩子,递归到某一深度一定会有左孩子或右孩子是满二叉树,如果是满二叉树可以根据深度k计算节点数为2^k-1。

具体思路可以参考代码随想录。

后序遍历参考代码1

int countNodes(struct TreeNode* root) {
    if (root == NULL) {
        return 0;
    }

    int lcnt = countNodes(root->left);
    int rcnt = countNodes(root->right);

    return 1 + lcnt + rcnt;    
}

后序遍历参考代码2

// 根据完全二叉树特性
int countNodes(struct TreeNode* root) {
    if (root == NULL) {
        return 0;
    }

    int lcnt = 0, rcnt = 0;
    struct TreeNode* lnode = root->left;
    struct TreeNode* rnode = root->right;

    while (lnode) {
        lnode = lnode->left;
        lcnt++;
    }
    while (rnode) {
        rnode = rnode->right;
        rcnt++;
    }

    if (lcnt == rcnt) {
        return (2 << lcnt) - 1;
    }
    return 1 +  countNodes(root->left) + countNodes(root->right);
}
代码随想录算法训练营第十六|104.二叉树最大深度111.二叉树最小深度222.完全二叉树节点个数 代码代码随想录算法训练营第十六|104.二叉树最大深度111.二叉树最小深度222.完全二叉树节点个数 阅读详情

相关推荐

代码随想录算法训练营第十六 | 104.二叉树最大深度、559.n叉树的最大深度111.二叉树最小深度222.完全二叉树节点个数

二叉树不一样的是,需要先遍历每一个孩子的下的深度,每次遍历都和最大深度相比较。

Danny_8的博客 1662

代码随想录算法训练营第十六 | 104.二叉树最大深度111. 二叉树最小深度222. 完全二叉树节点个数

我来举一个典型的例子如题:完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。完全二叉树(一)如图:完全二叉树(二)如图:可以看出如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量。

DongVeg的博客 874

代码随想录算法训练营第十六|104.二叉树最大深度 559.n叉树的最大深度111.二叉树最小深度222.完全二叉树节点个数

代码随想录题解:​​​​​​​。

qq_42973684的博客 812

Python - 代码随想录算法训练营第十六 | LeetCode104.二叉树最大深度 559.n叉树的最大深度、LeetCode111.二叉树最小深度、LeetCode222.完全二叉树

的内容仍然是二叉树。基本都是用长度法做的,递归等二刷再用。二叉树的递归法还需要再继续学习。二叉树的迭代法已经很熟悉了。​。

m0_53503719的博客 1076

代码随想录算法训练营第十六 | 104.二叉树最大深度 559.n叉树的最大深度111.二叉树最小深度222.完全二叉树节点个数

对于情况一,可以直接用。

qwerty0157的博客 831

代码随想录算法训练营第十六 | 104.二叉树最大深度111.二叉树最小深度222.完全二叉树节点个数

完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。方案二:递归法,要注意的点比较多,虽然是取最小深度,但是必须是到叶子节点深度,因此只要当前节点有子节点,就要递归获取,如果有两个子节点,就递归获取到叶子节点深度更小的深度。方案二:递归法,递归获取子树的深度,要注意边界条件的设置,是遍历到空指针返回深度0,然后因为要取最大深度,所以取左右子树中更深的一个,再加上本节点的一层,然后返回结果。这也是本题的考察目的。

Tong_1024_的博客 1051

二刷代码随想录算法训练营第十六 | 104.二叉树最大深度 559.n叉树的最大深度111.二叉树最小深度222.完全二叉树节点个数

使用前序求的就是深度,使用后序求的是高度。深度指的是从root视角向下,高度是叶子节点向上。

magic2142028406的博客 1044

代码随想录算法训练营第十六| LeetCode 104. 二叉树最大深度111.二叉树最小深度222.完全二叉树节点个数

学习了求二叉树深度的各种算法

qq_64336203的博客 1069

代码随想录算法训练营第十六| LeetCode104.二叉树最大深度、LeetCod559.n叉树的最大深度、LeetCode111.二叉树最小深度、LeetCode222.完全二叉树节点个数

深度:根节点到该节点节点数,主要用前序遍历。高度:该节点到叶子节点节点数,主要用后序遍历。本题中的最大深度,即为二叉树的高度,所以选择使用后序遍历。在这个过程中没有单独设置一个变量来记录层数,而是使用遍历到末端节点后逐次加一得到的。

m0_49342683的博客 1084

代码随想录算法训练营第十六104.二叉树最大深度111.二叉树最小深度222.完全二叉树节点个数

给定一个二叉树root,返回其最大深度二叉树的是指从根节点到最远叶子节点的最长路径上的节点数。

weixin_42797677的博客 794

代码随想录算法训练营第十六 | 二叉树深度节点个数

1、对递归理解进一步加深,后序理解透彻,前序理解一般,迭代没有理解2、对于完全二叉树,要充分理解其特性3、今题目都需要二刷代码随想录

Fight___的博客 1170

代码随想录算法训练营第十六 |104.二叉树最大深度111.二叉树最小深度222.完全二叉树节点个数(待补充)

我来举一个典型的例子如题:完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。对于情况一,可以直接用 2^树深度 - 1 来计算,注意这里根节点深度为1。对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。完全二叉树(一)如图:完全二叉树(二)如图:可以看出如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量。

wufaqidong1的博客 644

代码随想录算法训练营第十六104.二叉树最大深度、559. N叉树的最大深度111.二叉树最小深度222.完全二叉树节点个数

的内容主要练习二叉树遍历的递归写法。在此,再重点明确一下: 确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。: 写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。: 确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

biuhuiui的博客 1111

代码随想录算法训练营第十六||104.二叉树最大深度111.二叉树最小深度222.完全二叉树节点个数

完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。在完全二叉树中,如果递归向左遍历的深度不等于递归向右遍历的深度,则说明不是满二叉树。对于情况二,分别递归左孩子,和右孩子,递归到某一深度一定会有左孩子或者右孩子为满二叉树,然后依然可以按照情况1来计算。可以看出如果整个树不是满二叉树,就递归其左右孩子,直到遇到满二叉树为止,用公式计算这个子树(满二叉树)的节点数量。本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。

weixin_48040500的博客 803

代码随想录算法训练营第十六 |LeetCode104.二叉树最大深度、LeetCode111.二叉树最小深度、LeetCode完全二叉树节点个数

之前用了层序遍历的模板,迭代法来做这道题,这次试试看递归法。

m0_64514622的博客 686
上一篇: 代码随想录算法训练营第十五天 | 102.二叉树的层序遍历,226.翻转二叉树,101.对称二叉树 [二叉树篇]
下一篇: 代码随想录算法训练营第十七天 | 110.平衡二叉树,257. 二叉树的所有路径,404.左叶子之和 [二叉树篇]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值