代码随想录算法训练营第16天 104.二叉树的最大深度 111.二叉树的最小深度 222.完全二叉树的节点个数
104.二叉树的最大深度
如果一个树为空,那么它的最大深度就是0。否则,树的最大深度就是左子树的最大深度和右子树的最大深度中的较大值,再加上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) {
// 如果节点为空(说明已经到了叶子节点的下一层),返回深度为0
if (root == null) {
return 0;
} else {
// 递归地计算左子树的深度
int leftDepth = maxDepth(root.left);
// 递归地计算右子树的深度
int rightDepth = maxDepth(root.right);
// 返回左、右子树深度的较大值,再加上1(加上当前层)
return Math.max(leftDepth, rightDepth) + 1;
}
}
}
111.二叉树的最小深度
计算最小深度时,如果一个节点只有左子树或只有右子树,那么它的最小深度实际上应该是它的左子树或右子树的最小深度+1,而不是直接返回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) {
if (root == null) {
return 0;
}
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
// 如果左子树为空,返回右子树的最小深度+1
if(root.left == null) {
return rightDepth + 1;
}
// 如果右子树为空,返回左子树的最小深度+1
if(root.right == null) {
return leftDepth + 1;
}
// 如果左右子树都不为空,返回左、右子树深度的较小值,再加上1(加上当前层)
return Math.min(leftDepth, rightDepth) + 1;
}
}
222.完全二叉树的节点个数
如果二叉树是空的,那么节点个数就是0。否则,节点个数就是左子树的节点个数加上右子树的节点个数,再加上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;
}
return countNodes(root.left)+countNodes(root.right)+1;
}
}
然而,对于完全二叉树,我们可以进行优化。如果左子树的高度等于右子树的高度,那么左子树是满的,我们可以直接得到左子树的节点数,然后递归计算右子树的节点数。如果左子树的高度不等于右子树的高度,那么右子树是满的但是高度较小,我们可以直接得到右子树的节点数,然后递归计算左子树的节点数。
优化后的代码如下:
class Solution {
public int countNodes(TreeNode root) {
// 如果根节点为空,则返回0
if (root == null) {
return 0;
}
// 计算树的深度
int d = depth(root);
// 判断是否右子树的深度等于总深度-1,如果是,说明左子树是满二叉树,我们可以直接得到左子树的节点数
if (d - 1 == depth(root.right)) {
// 1 << d 是 2 的 d 次方,表示满二叉树的节点数量,然后递归计算右子树的节点数量
return (1 << d) + countNodes(root.right);
} else {
// 如果不是,说明右子树是满二叉树,但深度小一些,我们可以直接得到右子树的节点数量,然后递归计算左子树的节点数量
return (1 << (d - 1)) + countNodes(root.left);
}
}
private int depth(TreeNode node) {
int depth = 0;
// 计算树的最大深度,完全二叉树的深度可以通过左子树来计算
while (node != null) {
depth++;
node = node.left;
}
return depth;
}
}