104.二叉树的最大深度 | 559.n叉树的最大深度
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。
二叉树节点的深度:指从根节点到该节点的最长简单路径边的条数或者节点数(取决于深度从0开始还是从1开始)
二叉树节点的高度:指从该节点到叶子节点的最长简单路径边的条数或者节点数(取决于高度从0开始还是从1开始)
思路:根节点的高度就是二叉树的最大深度,所以本题中我们通过后序求的根节点高度来求的二叉树最大深度。
递归法:
- 递归参数:结点
- 递归终止条件:空结点
- 单层递归逻辑:后序遍历:左右中。先计算左子树的高度,再计算右子树的高度,取最大。
class Solution {
//确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。
public int maxDepth(TreeNode root) {
//确定终止条件:如果为空节点的话,就返回0,表示高度为0。
if(root==null){
return 0;
}
int leftdepth=maxDepth(root.left);
int rightdepth=maxDepth(root.right);
return Math.max(leftdepth, rightdepth)+1;
}
}
同样的n叉树,也是一样的思路
只不过,左右结点变成child结点list
class Solution {
public int maxDepth(Node root) {
if(root==null){
return 0;
}
int maxChildDepth = 0;
List<Node> children = root.children;
for(Node child:children){
int depth=maxDepth(child);
maxChildDepth=Math.max(maxChildDepth, depth);
}
return maxChildDepth+1;
}
}
111.二叉树的最小深度
理解最小深度:从 根节点 到 最近叶子节点的 最短路径上的 结点数量
思路:层序遍历法(比较好理解)
- 层序遍历,获得一个层序序列 { [3], [9,20] , [15,7] }
- 然后遍历这个序列,遍历每一层结点,碰到第一个叶子结点,就返回深度。
/**
* 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;
}
return Order(root);
}
//层序遍历存储每一层
public int Order(TreeNode root){
int minDepth=1;//根节点本身就是一层,从1开始
Queue<TreeNode> q=new LinkedList<TreeNode>();
//将根节点入队
q.offer(root);
while(!q.isEmpty()){
List<TreeNode> list=new ArrayList<>();
int len=q.size();
//同一层的结点
while(len>0){
TreeNode node=q.poll();
//list.add(node);
//判断是否是叶子结点
if(ifLeaf(node)){
return minDepth;
}
if(node.left!=null){
q.offer(node.left);
}
if(node.right!=null){
q.offer(node.right);
}
len--;
}
minDepth++;//进入下一层
}
return minDepth;
}
/**
判断是否是叶子结点
*/
private boolean ifLeaf(TreeNode node){
if(node.left==null&&node.right==null){
return true;
}
return false;
}
}
递归法:
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.完全二叉树的节点个数
思路:层序遍历
- 获得一个层序遍历序列:[[1],[2,3],[4,5,6]]
- 题目已经明确给我们的是一个完全二叉树了,完全二叉树的概念就是除了最后一层之后,都是满的,不存在叶子节点。
- 比如这个二叉树有n层,那么我们可以计算n-1层的结点数=2*(n-1)-1 ,题中n=3,那么前两层的结点数就是2*2-1=3。
- 我们只需要取出层序遍历序列的最后一个list,计算它有多少个结点就好了,再加上前n-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;
}
List<List<TreeNode>> list=Order(root);
//因为题目给我们的是一个完全二叉树,所以只需要取出最后一层
int layer=list.size();//计算一共有几层
List<TreeNode> lastLayer=list.get(list.size()-1);//取出最后一层
int lastlayer=lastLayer.size();
//上一层的完全二叉树+最后一层
int last = (int)Math.pow(2, layer-1)-1;
return last+lastlayer;
}
public List<List<TreeNode>> Order(TreeNode node){
List<List<TreeNode>> resList = new ArrayList<>();
//新建一个队列
Queue<TreeNode> que=new LinkedList<TreeNode>();
//将根节点入队
que.offer(node);
while(!que.isEmpty()){
List<TreeNode> itemList=new ArrayList<>();
int len=que.size();
while(len>0){
TreeNode tmpNode=que.poll();//获取当前队列的队头元素
itemList.add(tmpNode);//将值存入list中
//再判断队头元素的左右孩子是否存在
if(tmpNode.left!=null){
que.offer(tmpNode.left);
}
if(tmpNode.right!=null){
que.offer(tmpNode.right);
}
len--;
}
resList.add(itemList);
}
return resList;
}
}
递归法:计算左右结点的个数
class Solution {
// 通用递归解法
public int countNodes(TreeNode root) {
if(root == null) {
return 0;
}
return countNodes(root.left) + countNodes(root.right) + 1;
}
}