104.二叉树的最大深度 (优先掌握递归)
这道题与上一篇文章中的102.层序遍历相同。
只不过102这道题目的要求是存储二叉树中的每一层的节点,而此题是计算二叉树的最大深度。
代码如下:
/**
* 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) {
if(root==null)
return 0;
Queue<TreeNode> queue=new LinkedList<>();
//因为此时根节点不为空,所以depth初始化为1
int depth=0;
queue.offer(root);
while(!queue.isEmpty()){
//每次进入外层循环,层数+1
depth++;
//获取当前队列的元素个数
int len=queue.size();
while(len>0){
//内层循环做两件事
//1、排空队列中当前层数的所有节点
//2、依据层序遍历,将下一层节点加入到队列中
TreeNode curNode=queue.poll();
if(curNode.left!=null)
queue.offer(curNode.left);
if(curNode.right!=null)
queue.offer(curNode.right);
len--;
}
}
return depth;
}
}
递归方法
-
针对二叉树的题目,刷了这么些题,如果在最初始时考虑使用递归——那么在递归的细节当中要不然考虑二叉树的前序遍历、要不然考虑二叉树的后序遍历
-
关于二叉树的深度以及高度的概念。
-
- 二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
- 二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
递归方法1:使用二叉树的后序遍历——通过二叉树的高度来算深度
再次重复递归三要素:
-
递归函数的返回值是什么?形参是什么?
-
递归函数内部在什么时候return
-
每一轮递归,其细节处理是什么
一旦上面递归三要素确定了,之后就只需要考虑递归的调用顺序。
class Solution {
public int maxDepth(TreeNode root) {
return CalcDepth(root);
}
public int CalcDepth(TreeNode node){
if(node==null){
return 0;
}
//计算其左子树的高度
int leftDepth=CalcDepth(node.left);
//计算其右子树的高度
int rightDepth=CalcDepth(node.right);
int depth=Math.max(leftDepth,rightDepth)+1;
return depth;
}
}
111.二叉树的最小深度 (优先掌握递归)
class Solution {
//还是考虑迭代法层序遍历
//基本思路是遍历每一层的时候,只要当前层数有叶子节点,那么就可以直接return了;此时就没有必要再继续遍历下去
public int minDepth(TreeNode root) {
if(root==null)
return 0;
Queue<TreeNode> queue=new LinkedList<>();
int minDepth=0;
queue.offer(root);
while(!queue.isEmpty()){
minDepth++;
int len=queue.size();
while(len>0){
TreeNode node=queue.poll();
len--;
if(node.left!=null)
queue.offer(node.left);
if(node.right!=null)
queue.offer(node.right);
if(node.left==null && node.right==null)
return minDepth;
}
}
return minDepth;
}
}
使用递归的方法来完成求解
使用后序遍历——左右中,但是这里与二叉树的最大深度不同的地方在于:最小深度 是根节点到最近叶子节点的最短路径上的节点数量。
所以,如果左子树为空,右子树不为空,说明最小深度是 1 + 右子树的深度。
反之,右子树为空,左子树不为空,最小深度是 1 + 左子树的深度。 最后如果左右子树都不为空,返回左右子树深度最小值 + 1 。
class Solution {
/**
* 递归法,相比求MaxDepth要复杂点
* 因为最小深度是从根节点到最近**叶子节点**的最短路径上的节点数量
*/
public int minDepth(TreeNode root) {
if (root == null) {
return 0;
}
int leftDepth = minDepth(root.left);
int rightDepth = minDepth(root.right);
if (root.left == null) {
return rightDepth + 1;
}
if (root.right == null) {
return leftDepth + 1;
}
// 左右结点都不为null
return Math.min(leftDepth, rightDepth) + 1;
}
}
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 {
//考虑使用迭代的方法前序遍历二叉树,来完成节点个数的统计
int nodeNum=0;
public int countNodes(TreeNode root) {
if(root==null)
return 0;
preOrder(root);
return nodeNum;
}
public void preOrder(TreeNode node){
//前序遍历顺序————中左右
if(node==null)
return;
//每次遇到节点,nodeNum+1
nodeNum++;
preOrder(node.left);
preOrder(node.right);
}
}