学习内容
力扣算法
104.二叉树的最大深度
111.二叉树的最小深度
222.完全二叉树的节点个数
110.平衡二叉树
具体内容
104.二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
给定二叉树 [3,9,20,null,null,15,7],
返回它的最大深度 3 。
做题思路
递归
由于计算个数,因此可通过从后往前获取遍历返回值,再不断相加返回值而得出最终结果
迭代
求最大深度,即根节点到最远叶子的最长路径的节点数,可看出求层数
解题
递归
class Solution {
public int maxDepth(TreeNode root) {
//由于参数刚好相同,不用再另写方法
//写边界条件
if(root == null){
return 0;
}
//获取每次的返回值
int left = maxDepth(root.left);
int fight = maxDepth(root.right);
int depth = 1 + Math.max(left,right);
return depth;
}
}
迭代
class Solution {
//迭代,使用队列
public int maxDepth(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
if(root != null){
queue.add(root);
}
//代表层数
int result = 0;
while(!queue.isEmpty()){
//由于计算的是层数,则需要算出队列长度。方便下面程序进行循环
int size = queue.size();
result++;
while(size-- > 0){
TreeNode node = queue.poll();
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
}
return result;
}
}
111. 二叉树的最小深度
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6] 输出:5
做题思路
递归
此题求最小值,要考虑到当根节点的左子树为空或者右子树为空的情况,若根节点左子树为空,则最小值是1+右子树的最小深度;若根节点右子树为空,则最小值是1+左子树的最小深度
如下图,最小深度是3
迭代
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。与求最大深度相反,若是遇到子节点为空,则可直接返回
解题
递归
class Solution {
public int minDepth(TreeNode root) {
if(root == null){return 0;}
int left = minDepth(root.left);
int right = minDepth(root.right);
//之所以加1 是加上左子树或者右子树的根节点
if(root.left == null){
return 1+right;
}
if(root.right == null){
return 1+left;
}
//之所以加1 是加上本来的根节点
return Math.min(left,right)+1;
}
}
迭代
class Solution {
public int minDepth(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
if(root != null){
queue.offer(root);
}
int result = 0;
while(!queue.isEmpty()){
int size = queue.size();
result++;
while(size-- > 0){
TreeNode node = queue.poll();
//注意叶子节点是指没有子节点的,因此这里使用&&
if(node.left == null && node.right == null){
return result;
}
if(node.left != null){queue.offer(node.left);}
if(node.right != null){queue.offer(node.right);}
}
}
return result;
}
}
222. 完全二叉树的节点个数
给你一棵 完全二叉树 的根节点 root ,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层,则该层包含 1~ 2h 个节点。
示例 1:
输入:root = [1,2,3,4,5,6] 输出:6
示例 2:
输入:root = [] 输出:0
示例 3:
输入:root = [1] 输出:1
提示:
树中节点的数目范围是[0, 5 * 104]
0 <= Node.val <= 5 * 104
题目数据保证输入的树是 完全二叉树
做题思路
递归
类似于求最大深度,从后往前
迭代
可以利用队列,再用一个变量计算树的不为空的节点个数
解题
递归
//求普通二叉数的节点数
class Solution {
public int countNodes(TreeNode root) {
if(root == null){return 0;}
int left = countNodes(root.left);
int right = countNodes(root.right);
int depth = left + right +1;
return depth;
}
}
//求完全二叉数的节点数,利用完全二叉树的特性,完全二叉树有一侧是满二叉树
//求满二叉树的节点是(2^层数) -1
class Solution {
public int countNodes(TreeNode root) {
//递归终止条件
if(root == null){return 0;}
//单层逻辑
//求左子树和右子树
TreeNode left = root.left;
TreeNode right = root.right;
//变量分别代表左右两边的子树
int leftNum=0;
int rightNum=0;
//计算的是左右外侧的层数,因此条件都是左子树的左子树,右子树的右子树
while(left != null){
left = left.left;
leftNum++;
}
while(right != null){
right = right.right;
rightNum++;
}
//递归,调用上面的逻辑
int l=countNodes(root.left);
int r=countNodes(root.right);
return l+r+1;
}
}
迭代
class Solution {
public int countNodes(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
if(root != null){
queue.offer(root);
}
int result = 0;
while(!queue.isEmpty()){
TreeNode node = queue.poll();
result++;
if(node.left != null){
queue.offer(node.left);
}
if(node.right != null){
queue.offer(node.right);
}
}
return result;
}
}
110. 平衡二叉树
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:
一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:true
示例 2:
输入:root = [1,2,2,3,3,null,null,4,4] 输出:false
示例 3:
输入:root = [] 输出:true
题目地址
解题思路
高度是某节点距离叶子节点的距离,使用后序遍历;
深度是某节点距离根节点的距离,使用前序遍历;
判断是否为平衡二叉树,即左子树和右子树的高度差是否大于1,若大于1,则不是平衡二叉树。
解题
递归
class Solution {
public boolean isBalanced(TreeNode root) {
return result(root) != -1;
}
//返回的是高度差返回值是int类型,参数是TreeNode
public int result(TreeNode root){
if(root == null){return 0;}
//后序遍历 左右中
int leftNode = result(root.left);
if(leftNode == -1){
return -1;
}
int rightNode = result(root.right);
if(rightNode == -1){
return -1;
}
// 左右子树高度差大于1,return -1表示已经不是平衡树了
if (Math.abs(leftNode - rightNode) > 1) {
return -1;
}else{
return 1+Math.max(leftNode,rightNode);
}
}