代码随想录刷题记录day15之 二叉树的最大深度+二叉树的最小深度+完全二叉树的节点个数
104. 二叉树的最大深度
二叉树的深度、高度
下面的图是从1开始计算,有些是从0开始计算,这只是一个规则。
思想
前序遍历,求二叉树根节点的高度,就是二叉树的最大的深度。
过程如下图所示。
前序遍历:
用一个result去记录深度,需要有回溯的过程,避免深度被重复计算了。
在这里插入图片描述
代码
后序遍历
class Solution {
public int maxDepth(TreeNode root) {
return deep(root);
}
//先用递归尝试一下 后序遍历
public int deep(TreeNode node){
if(node==null) return 0;
int l=deep(node.left);
int r=deep(node.right);
return 1+Math.max(l,r);
}
}
前序遍历
class Solution {
int result=0;
public int maxDepth(TreeNode root) {
if(root==null) return 0;
deep(root,1);
return result;
}
//先用递归尝试一下 后序遍历
// public int deep(TreeNode node){
// if(node==null) return 0;
// int l=deep(node.left);
// int r=deep(node.right);
// return 1+Math.max(l,r);
// }
public void deep(TreeNode node,int deepth){
//前序遍历
result=deepth>result?deepth:result;
if(node==null) return ;
if(node.left!=null){
deepth++;
deep(node.left,deepth);
deepth--;
}
if(node.right!=null){
deepth++;
deep(node.right,deepth);
deepth--;
}
}
}
迭代法
public int maxDepth(TreeNode root) {
//层序遍历
if(root==null) return 0;
int sum=0;
Queue<TreeNode> queue=new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size=queue.size();
for(int i=0;i<size;i++){
TreeNode temp= queue.poll();
if(i==size-1){
sum+=1;//这样就只计算一层了
}
// sum+=1;//这样会计算所有的节点的个数
if(temp.left!=null) queue.offer(temp.left);
if(temp.right!=null) queue.offer(temp.right);
}
}
return sum;
}
111. 二叉树的最小深度
思想:
踩坑了,刚做完最大深度,以为只要把后序遍历中的 max改成min就好了,但这样会把左边子树为空,右边子树不为空 或者 右边子树为空 左边子树为空 两者情况 返回1,即根节点的最小深度。但是按照题意不是正确答案,如下图。
最小深度是3
所以需要把这两种条件排除在外。
代码
class Solution {
public int minDepth(TreeNode root) {
return minDeep(root);
}
//返回比较小的 深度
public int minDeep(TreeNode node){
if(node==null) return 0;
int left=minDeep(node.left);
int right=minDeep(node.right);
//可能会出现 左边的子树为空,右边子树不为空的情况。
if(node.left==null &&node.right!=null){
return 1+right;
}
if(node.left!=null && node.right==null){
return 1+left;
}
return 1+Math.min(left,right);
}
}
222. 完全二叉树的节点个数
思想
1.普通二叉树的前序遍历,也需要遍历所有的节点
2.根据普通二叉树的后序遍历,需要遍历所有的节点
3.利用完全二叉树的特性,判断子树是否是满二叉树,只要遍历左边节点和右边节点即可,满二叉树的节点的个数是 2^deepth-1,其中deepth为满二叉树的深度。2<<0 =21,2<<1=22。
代码
前序遍历
private int result=0;
public int countNodes(TreeNode root) {
if(root==null) return 0;
countPre(root);
return result+1;
}
public void countPre(TreeNode node){
//前序遍历
//递归终止条件
if(node==null) {
return ;
}
if(node.left!=null){
result++;
countPre(node.left);
}
if(node.right!=null){
result++;
countPre(node.right);
}
}
后序遍历
public int countNodes(TreeNode root) {
//递归调用
return count(root);
}
public int count(TreeNode node){
//递归终止条件
//此种遍历方式 是后序遍历 左右中
if(node==null) return 0;
//求左 子树的节点的个数
int left=count(node.left);
int right=count(node.right);
return 1+left+right;
}
根据完全二叉树的特性进行遍历
public int countNodes(TreeNode root) {
return countAb(root);
}
public int countAb(TreeNode node){
//利用完全二叉树的特性去解这道题目
if(node==null) return 0;
TreeNode left=node.left;
TreeNode right=node.right;
int leftDepth=0,rightDepth=0;
while(left!=null){
left=left.left;
leftDepth++;
}
while(right!=null){
right=right.right;
rightDepth++;
}
if(leftDepth==rightDepth){
//说明是一个满二叉树
return (2<<leftDepth)-1;
}
//不是一个满二叉树 就进行递归
return 1+countAb(node.left)+countAb(node.right);
}