代码随想录算法训练营第16天 | 104.二叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数
104.二叉树的最大深度
题目:104.二叉树的最大深度
文档讲解:代码随想录-104.二叉树的最大深度
视频讲解:哔哩哔哩-104.二叉树的最大深度
状态/时间:没写出来/三十分钟
思路:
最大深度其实就是结点到根结点的深度,而高度是跟结点到最后一个结点的高度。
利用这个特性就可以用后序遍历,计算出左右子树的最大高数,取一个左右子树的最大高度加上 1 即二叉树的最大深度
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
return getHeight(root);
}
// 后序遍历
public int getHeight(TreeNode node) {
if (node == null) {
return 0;
}
// 左
int leftHeight = getHeight(node.left);
// 右
int rightHeight = getHeight(node.right);
// 中
int max = 1 + Math.max(leftHeight, rightHeight);
return max;
}
}
注意:
111.二叉树的最小深度
题目:111.二叉树的最小深度
文档讲解:代码随想录-111.二叉树的最小深度
视频讲解:哔哩哔哩-111.二叉树的最小深度
状态/时间:没写出来/三十分钟
思路:
最小深度是指:根节点到最小叶子的结点。
还是跟上一题一样,采用后序遍历,大家可以想到max改为min。但是这里有个代码误区,就是如果左子树为空,右子树不为空,那么返回的会是 1 了,而题意并不是这样,所以要判断: 左子树为空,右子树不为空 以及 右子树为空,左子树不为空的情况。
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
return getHeight(root);
}
public int getHeight(TreeNode node) {
if (node == null) {
return 0;
}
// 左
int leftHeight = getHeight(node.left);
// 右
int rightHeight = getHeight(node.right);
// 左为空, 右不为空
if (node.left == null && node.right != null) {
// 返回子树的长度 + 根节点
return 1 + rightHeight;
}
if (node.right == null && node.left != null) {
return 1 + leftHeight;
}
// 两个都不为空的情况
int res = 1 + Math.min(leftHeight, rightHeight);
return res;
}
}
注意:
左子树为空,右子树不为空 以及 右子树为空,左子树不为空的情况。
222.完全二叉树的节点个数
题目:222.完全二叉树的节点个数
文档讲解:代码随想录-222.完全二叉树的节点个数
视频讲解:哔哩哔哩-222.完全二叉树的节点个数
状态/时间:没写出来/三十分钟
法一:
思路:
当成普通的二叉树进行处理,可以用前中后层序计算,后序最为方便。
代码:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
return count(root);
}
// 后序遍历
public int count(TreeNode node) {
if (node == null) {
return 0;
}
int leftCount = count(node.left);
int rightCount = count(node.right);
int res = leftCount + rightCount + 1;
return res;
}
}
注意:
记得加上根节点。
法二:
思路
因为完全二叉树,可以利用完全二叉树的特性来操作。看左侧深度 == 右侧深度。有个计算完全二叉树所有结点的公式是2的n次方-1
代码
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int countNodes(TreeNode root) {
if (root == null) {
return 0;
}
TreeNode left = root.left;
TreeNode right = root.right;
int leftDepth = 0;
int rightDepth = 0;
int res = 0;
// 求左子树的深度
while (left != null) {
left = left.left;
leftDepth++;
}
// 求右子树的深度
while (right != null) {
right = right.right;
rightDepth++;
}
if (leftDepth == rightDepth) {
return (2 << leftDepth) - 1;
}
return countNodes(root.left) + countNodes(root.right) + 1;
}
}
注意