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

简介: 代码随想录训练营day16|104.二叉树的最大深度 559.n叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数...

前言

代码随想录算法训练营day16


一、Leetcode 104.二叉树的最大深度

1.题目

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例: 给定二叉树 [3,9,20,null,null,15,7],

3

/ \ 9 20 / \ 15 7

返回它的最大深度 3 。

来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/maximum-depth-of-binary-tree

2.解题思路

解题思路

1. 标签:DFS
2. 找出终止条件:当前节点为空
3. 找出返回值:节点为空时说明高度为 00,所以返回 00,节点不为空时则分别求左右子树的高度的最大值,同时加 11 表示当前节点的高度,返回该数值
4. 某层的执行过程:在返回值部分基本已经描述清楚
5. 时间复杂度:O(n)O(n)

3.代码实现

```java /** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ class Solution { public int maxDepth(TreeNode root) { if(root == null) { return 0; } else { int left = maxDepth(root.left); int right = maxDepth(root.right); return Math.max(left, right) + 1; } } }

```

二、Leetcode 559.n叉树的最大深度

1.题目

给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。

示例 1:

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

示例 2:

输入: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] 输出:5

提示:

1. 树的深度不会超过 1000 。
2. 树的节点数目位于 [0, 104] 之间。

来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/maximum-depth-of-n-ary-tree

2.解题思路

方法一:深度优先搜索

如果根节点有 NN 个子节点,则这 NN 个子节点对应 NN 个子树。记 NN 个子树的最大深度中的最大值为 maxChildDepthmaxChildDepth,则该 NN 叉树的最大深度为 maxChildDepth+1maxChildDepth+1。

每个子树的最大深度又可以以同样的方式进行计算。因此我们可以用「深度优先搜索」的方法计算 NN 叉树的最大深度。具体而言,在计算当前 NN 叉树的最大深度时,可以先递归计算出其每个子树的最大深度,然后在 O(1)O(1) 的时间内计算出当前 NN 叉树的最大深度。递归在访问到空节点时退出。

3.代码实现

```java class Solution { public int maxDepth(Node root) { if (root == null) { return 0; } int maxChildDepth = 0; List children = root.children; for (Node child : children) { int childDepth = maxDepth(child); maxChildDepth = Math.max(maxChildDepth, childDepth); } return maxChildDepth + 1; } }

```

三、Leetcode 111.二叉树的最小深度

1.题目

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

说明:叶子节点是指没有子节点的节点。

示例 1:

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

示例 2:

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

提示:

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

2.解题思路

方法一:深度优先搜索

首先可以想到使用深度优先搜索的方法,遍历整棵树,记录最小深度。

对于每一个非叶子节点,我们只需要分别计算其左右子树的最小叶子节点深度。这样就将一个大问题转化为了小问题,可以递归地解决该问题。

3.代码实现

```java class Solution { public int minDepth(TreeNode root) { if (root == null) { return 0; }

1. if (root.left == null && root.right == null) {
2. return 1;
3.     }
4. 
5.     int min_depth = Integer.MAX_VALUE;
6. if (root.left != null) {
7.         min_depth = Math.min(minDepth(root.left), min_depth);
8.     }
9. if (root.right != null) {
10.         min_depth = Math.min(minDepth(root.right), min_depth);
11.     }
12. 
13. return min_depth + 1;
14. }

}

```

四、Leetcode 222.完全二叉树的节点个数

1.题目

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

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

示例 1:

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

示例 2:

输入:root = [] 输出:0

示例 3:

输入:root = [1] 输出:1

提示:

1. 树中节点的数目范围是[0, 5 * 104]
2. 0 <= Node.val <= 5 * 104
3. 题目数据保证输入的树是 完全二叉树

2.解题思路

方法一:二分查找 + 位运算

对于任意二叉树,都可以通过广度优先搜索或深度优先搜索计算节点个数,时间复杂度和空间复杂度都是 O(n)O(n),其中 nn 是二叉树的节点个数。这道题规定了给出的是完全二叉树,因此可以利用完全二叉树的特性计算节点个数。

规定根节点位于第 00 层,完全二叉树的最大层数为 hh。根据完全二叉树的特性可知,完全二叉树的最左边的节点一定位于最底层,因此从根节点出发,每次访问左子节点,直到遇到叶子节点,该叶子节点即为完全二叉树的最左边的节点,经过的路径长度即为最大层数 hh。

当 0≤i

当最底层包含 11 个节点时,完全二叉树的节点个数是

∑i=0h−12i+1=2hi=0∑h−12i+1=2h

当最底层包含 2h2h 个节点时,完全二叉树的节点个数是

∑i=0h2i=2h+1−1i=0∑h2i=2h+1−1

因此对于最大层数为 hh 的完全二叉树,节点个数一定在 [2h,2h+1−1][2h,2h+1−1] 的范围内,可以在该范围内通过二分查找的方式得到完全二叉树的节点个数。

具体做法是,根据节点个数范围的上下界得到当前需要判断的节点个数 kk,如果第 kk 个节点存在,则节点个数一定大于或等于 kk,如果第 kk 个节点不存在,则节点个数一定小于 kk,由此可以将查找的范围缩小一半,直到得到节点个数。

如何判断第 kk 个节点是否存在呢?如果第 kk 个节点位于第 hh 层,则 kk 的二进制表示包含 h+1h+1 位,其中最高位是 11,其余各位从高到低表示从根节点到第 kk 个节点的路径,00 表示移动到左子节点,11 表示移动到右子节点。通过位运算得到第 kk 个节点对应的路径,判断该路径对应的节点是否存在,即可判断第 kk 个节点是否存在。

3.代码实现

```java class Solution { public int countNodes(TreeNode root) { if (root == null) { return 0; } int level = 0; TreeNode node = root; while (node.left != null) { level++; node = node.left; } int low = 1 << level, high = (1 << (level + 1)) - 1; while (low < high) { int mid = (high - low + 1) / 2 + low; if (exists(root, level, mid)) { low = mid; } else { high = mid - 1; } } return low; }

1. public boolean exists(TreeNode root, int level, int k) {
2.     int bits = 1 << (level - 1);
3.     TreeNode node = root;
4.     while (node != null && bits > 0) {
5. if ((bits & k) == 0) {
6.             node = node.left;
7.         } else {
8.             node = node.right;
9.         }
10.         bits >>= 1;
11.     }
12. return node != null;
13. }

}

```


相关文章
|
1月前
【LeetCode 32】111.二叉树的最小深度
【LeetCode 32】111.二叉树的最小深度
16 0
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
代码随想录 Day13 二叉树 LeetCode T104 二叉树的最大深度 T111 二叉树的最小深度 T222完全二叉树的节点个数
57 0
|
6月前
【力扣】104. 二叉树的最大深度、111. 二叉树的最小深度
【力扣】104. 二叉树的最大深度、111. 二叉树的最小深度
|
6月前
|
C++ Python
leetcode-111:二叉树的最小深度
leetcode-111:二叉树的最小深度
43 0
|
算法
代码随想录算法训练营第十五天 | LeetCode 104. 二叉树的最大深度、559. N 叉树的最大深度、111.二叉树的最小深度、222. 完全二叉树的节点个数
代码随想录算法训练营第十五天 | LeetCode 104. 二叉树的最大深度、559. N 叉树的最大深度、111.二叉树的最小深度、222. 完全二叉树的节点个数
54 0
|
存储 算法 前端开发
前端算法-叉树的最大深度
前端算法-叉树的最大深度
|
存储 算法
算法训练Day17|● 104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
算法训练Day17|● 104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
|
机器学习/深度学习 存储 人工智能
代码随想录训练营day21| 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先...
代码随想录训练营day21| 530.二叉搜索树的最小绝对差 501.二叉搜索树中的众数 236. 二叉树的最近公共祖先...
剑指offer_二叉树---二叉树的深度
剑指offer_二叉树---二叉树的深度
67 0
Leetcode 111 二叉树最小深度
Leetcode 111 二叉树最小深度
129 0