代码随想录算法训练营第16天 | 二叉树part03 104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
题目一 104.二叉树的最大深度 559.n叉树的最大深度
part7 二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
注意:
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)深度是从上开始向下计算。
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)高度是从下开始向上计算。
可得,根节点的高度就是二叉树的最大深度.
本题中我们通过后序求的根节点高度来求的二叉树最大深度。
定单层递归的逻辑:
先求它的左子树的深度,再求右子树的深度,
最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)
就是目前节点为根节点的树的深度。
这种思路对多叉树也一样,对每个分叉的长度拉成一个数组,再取最大值。
class Solution
{
public int maxDepth(TreeNode root) {
return get(root);
}
public int get(TreeNode root)
{
if(root == null)
return 0;
int leftnum = get(root.left);
int rightnum = get(root.right);
return 1 + Math.max(leftnum, rightnum);
}
}
前序遍历的思路如下(中左右),需要考虑回溯:
public class solution
{
public int result;
public void getdepth(TreeNode node, int depth)
{
result = depth > result ? depth : result; // 中
if (node.left == null && node.right == null)
return ;
if (node.left != null)
{ // 左
depth++; // 深度+1
getdepth(node.left, depth);
depth--; // 回溯,深度-1
}
if (node.right != null)
{ // 右
depth++; // 深度+1
getdepth(node.right, depth);
depth--; // 回溯,深度-1
}
return ;
}
public int maxDepth(TreeNode root)
{
result = 0;
if (root == null)
return result;
getdepth(root, 1);
return result;
}
};
迭代法,使用层序遍历正好,因为计算的是层数。
注意是迭代,所以有for循环。
public class solution
{
public int maxDepth(Treenode root)
{
if(root == null)
return 0;
int depth = 0;
Queue<Treenode> que = new LinkedList<>();
que.push(root);
while(que.isEmpty() != true)
{
int len = que.size();
depth++;
for(int i=0; i<len; i++)
{
Treenode popnode = que.front();
que.pop();
if(popnode.left != null)
que.push(root.left);
if(popnode.rigth != null)
que.push(root.right);
}
}
return depth;
}
}
题目二 111.二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。注意是叶子节点。
什么是叶子节点,左右孩子都为空的节点才是叶子节点!
首先根节点自己如果左右节点仅缺少一个,也不能将自己视为叶子节点,必须接着向下寻找。
因此目标为,找到一个离根节点最近的叶子节点。
同样使用递归,关键是特殊情况:
左空,右不空,不是最低点;
右空,左不空,不是最低点;
class Solution {
public int minDepth(TreeNode root)
{
if(root == null)
return 0;
int leftnum = minDepth(root.left);
int rightnum = minDepth(root.right);
if(root.left == null && root.right != null)
return 1 + rightnum;
if(root.left != null && root.right == null)
return 1 + leftnum;
int depth = 1 + Math.min(leftnum, rightnum);
return depth;
}
}
题目三 222.完全二叉树的节点个数
给出一个完全二叉树,求出该树的节点个数。
示例 1:
- 输入:root = [1,2,3,4,5,6] 输出:6
示例 2: - 输入:root = [] 输出:0
首先用迭代法的话,根据完全二叉树的性质,用层序遍历正好能按顺序遍历。
这是一种方法。
class Solution {
public int countNodes(TreeNode root)
{
if(root == null)
return 0;
Queue<TreeNode> que = new LinkedList<>();
que.offer(root);
int count = 0;
while(que.isEmpty() != true)
{
int len = que.size();
for(int i=0; i<len; i++)
{
TreeNode popnode = que.poll();
count++;
if(popnode.left != null)
que.offer(popnode.left);
if(popnode.right != null)
que.offer(popnode.right);
}
}
return count;
}
}
而使用递归,上面的两种方法,我们使用后序遍历的时候,每次获取左右子树的根节点深度,再取它们之间的最大/最小值;而如果要计算全部节点数量,则只需将它们全部加起来,再加上根节点即可。
- 时间复杂度:O(n)
- 空间复杂度:O(log n),算上了递归系统栈占用的空间
class Solution
{
public int countNodes(TreeNode root)
{
if(root == null)
return 0;
int leftnum = countNodes(root.left);
int rightnum = countNodes(root.right);
int num = leftnum + rightnum + 1;
return num;
}
}