代码随想录算法训练营第十六天|104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数
104.二叉树的最大深度
问题简述:求出二叉树最大深度。
思考:这道题深度和高度没有区别,因为前一天的层次遍历,很快想到了可以用层次遍历。然后学习的递归方法,感觉自己虽然写出来了,但是从来没有考虑过自己到底用的是什么遍历方法。
层次遍历法算法思路:队列存入每层元素。不断将队头元素值存入List
,再将队头的左右节点再次存入List
,最后推出队头。此时队列中为下一层元素,不断循环,记录遍历层数,最后遍历完所有层元素。
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
class Solution {
public int maxDepth(TreeNode root) {
ArrayDeque<TreeNode> dq = new ArrayDeque<>();
//将跟结点存入栈
if (root != null) dq.push(root);
int deep = 0;
while (!dq.isEmpty()){
//用于遍历当前层元素
int a = dq.size();
//将当前层元素存入,并添加下一层元素
for (int i = 0; i < a; i++) {
if (dq.peekFirst().left != null) dq.add(dq.peekFirst().left);
if (dq.peekFirst().right != null) dq.add(dq.peekFirst().right);
dq.pop();
}
//记录层数
deep++;
}
return deep;
}
}
递归法算法思路:当前节点的深度为左右节点深度较大值加1,遍历方式为左右根。
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
int deep = 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
}
559.n叉树的最大深度
问题简述:求出n叉树最大深度。
思考:因为上一道题学会了递归方法,这道题也很快完成了递归,然后n叉树数据结构需要注意一下。
算法思路:当前节点的深度为所有节点深度最大值加1,遍历方式为后根遍历。
时间复杂度: O(n)
空间复杂度: O(1)
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
class Solution {
public int maxDepth(Node root) {
if (root == null) return 0;
int deep = 0;
//用max记录深度最大值
int max = 0;
for (Node n : root.children) {
max = Math.max(max, maxDepth(n));
}
return max+1;
}
}
111.二叉树的最小深度
问题简述:求出根结点到叶子结点的最小深度。
思考:感觉就是讨论不同的情况然后递归,左右节点都为空的为叶子节点,遍历方式还是左右根。
算法思路:判断当前节点如果为空,则返回最小深度0;判断当前节点有一个子结点为空,则当前深度为子结点最小深度加一;如果两个结点都存在的话,返回两个结点较小的深度。
时间复杂度 O(n)
空间复杂度 O(1)
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
class Solution {
public int minDepth(TreeNode root) {
if (root == null) return 0;
//如果左右结点都不存在的话,直接返回深度1
if (root.left == null && root.right == null){
return 1;
}
//如果一个结点存在的话,返回那那个结点的minDepth
if (root.left != null && root.right == null){
return minDepth(root.left) + 1;
}
if (root.left == null && root.right != null){
return minDepth(root.right) + 1;
}
//如果两个结点都存在的话,返回两个结点较小的
return Math.min(minDepth(root.left), minDepth(root.right))+1;
}
}
222.完全二叉树的节点个数
问题简述:求完全二叉树结点个数。
思考:正常求结点个数比较简单,而且超越用户也是100%。
递归算法思路:直接返回左右结点个数加一。
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 left = 0, right = 0;
TreeNode lNode = root;
TreeNode rNode = root;
while (lNode != null) {
left++;
lNode = lNode.left;
}
while (rNode != null) {
right++;
rNode = rNode.right;
}
//为满二叉树时间,直接返回结点个数
if (left == right) return (int) Math.pow(2, left) - 1;
//不为满二叉树,返回左右结点个数和再加1
return countNodes(root.left) + countNodes(root.right) + 1;
}
}
感想
感觉递归越来越熟悉,继续努力。