104.二叉树的最大深度
给定一个二叉树,找出其最大深度。 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树[3,9,20,null,null,15,7],返回它的最大深度 3 。
思路
在深度遍历中,将节点和当前层的层数depth作为参数进行迭代,当当前节点为空时,意味着完成了当前路径的遍历,当前路径的长度为depth -1,将该长度返回。
对于一个节点,它的深度与它的子树的深度相关,为其左、右子树的深度的较大值,因此,一个节点的深度为其左、右子树的深度的较大值,同理,一棵二叉树的深度为其根节点左、右子树的深度的较大值。
在层次遍历中,只要计算要二叉树的层数,即可计算该二叉树的深度。
代码
使用层序遍历,
class Solution {
public int maxDepth(TreeNode root) {
//方法1:层序遍历
if(root==null){
return 0;
}
if(root.left==null&&root.right==null){
return 1;
}
Deque<TreeNode> que=new LinkedList<>();
que.add(root);
int depth=0;
do{
depth++;
//加入结束符
que.add(null);
while(que.peek()!=null){
TreeNode node=que.poll();
if(node.left!=null){
que.add(node.left);
}
if(node.right!=null){
que.add(node.right);
}
}
//清除 结束符
que.poll();
}while(!que.isEmpty());
return depth;
}
}
使用深度遍历,
/**
* 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) {
int depth = travasal(root,1);
return depth;
}
private int travasal(TreeNode cur,int depth){
if(cur == null){
return depth - 1;
}
int leftDepth=0, rightDepth=0;
leftDepth = travasal(cur.left, depth + 1);
rightDepth =travasal(cur.right, depth + 1);
return Math.max(leftDepth,rightDepth);
}
}
559.n叉树的最大深度
给定一个 N 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。
思路
这道题使用层序遍历非常容易解决,解决方法与 104.二叉树的最大深度一样。
代码
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public int maxDepth(Node root) {
if(root == null){
return 0;
}
if(root.children.size() == 0){
return 1;
}
Deque<Node> que = new LinkedList<>();
Node node = null;
int depth = 0;
que.add(root);
do{
// 加入分隔符
que.add(null);
// 层数自增
depth++;
// 取出当前层的节点
while((node = que.poll()) != null){
// 将当前节点的所有孩子节点入队
for(int i=0;i<node.children.size();i++){
que.add(node.children.get(i));
}
}
}while(!que.isEmpty());
return depth;
}
}
111.二叉树的最小深度
给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
思路
使用层次遍历可以轻松解决这个问题。在层次遍历中,如果出现了叶子节点,则当前深度为二叉树的最小深度。
- 对根结点进行处理,
- 如果根节点为
null,即该二叉树是一棵空树,最小深度为。 - 否则,如果根节点没有左右孩子,则根节点是一个叶子节点,则最小深度为。
- 否则,进行层次遍历。
- 如果根节点为
- 在层次遍历中,在每一层中,
- 加入分隔符,
- 依次取出一个节点,直到取到分隔符,对于每一个节点,
- 如果该节点同时无左右孩子,跳出循环,并返回当前层数;
- 否则,将该节点的左右孩子(如果存在)入队。
- 返回层数。
如果使用递归遍历,那么对于一个节点,有以下三种情况:
- 有左子树,但无右子树,则 最小深度 = 左子树深度 + 1;
- 有右子树,但无左子树,则 最小深度 = 右子树深度 + 1;
- 同时有左右子树,或同时无左右子树,则 最小深度 = min(左子树深度, 右子树深度) + 1;此时,同时无左右子树是同时有左右子树的特殊情况,即 左子树深度 == 右子树深度 == 0 的情况。
- 由于一个节点的深度与左右子树的深度相关,在计算当前节点的深度时需要知道左右子树的存在情况及其深度。因此,在递归遍历中使用左右中的后序遍历方式。
代码
层序遍历的代码如下:
/**
* 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;
}
if(root.left == null && root.right == null){
return 1;
}
int depth = 0;
TreeNode node = null;
Deque<TreeNode> que = new LinkedList<>();
que.add(root);
outer:do{
que.add(null);
depth++;
while((node = que.poll()) != null){
if(node.left == null && node.right == null){
break outer;
}
if(node.left != null){
que.add(node.left);
}
if(node.right != null){
que.add(node.right);
}
}
}while(!que.isEmpty());
return depth;
}
}
递归方式的代码如下:
/**
* 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;
}
// 没有左子树,有右子树
// 最小深度为:右子树深度 + 1
if(root.left == null && root.right != null){
return 1 + minDepth(root.right);
}
// 有左子树,没有右子树
// 最小深度为:左子树深度 + 1
if(root.left != null && root.right ==null){
return 1 + minDepth(root.left);
}
// 同时有左右子树,或者同时没有左右子树
// 最小深度为: min(左子树深度,右子树深度) + 1
return 1 + Math.min(minDepth(root.left),minDepth(root.right));
}
}
222.完全二叉树的节点个数
给你一棵 完全二叉树 的根节点
root,求出该树的节点个数。
完全二叉树 的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第h层,则该层包含1~ 2h个节点。
222. 完全二叉树的节点个数 - 力扣(Leetcode)
思路
一棵满二叉树的节点数为 ,在一棵完全二叉树中,可以划分成多棵相同或不同高度的满二叉树组成(最小的一棵满二叉树可能是由一个节点组成),这样就可以利用满二叉树性质计算出树的节点个数。
判断一棵完全二叉树的子树是不是满二叉树的方法:
从该子树的根节点出发,分别计算它到子树最左边和最右边节点的节点数,如果相等,则该子树为满二叉树;否则,则这棵子树的最下面一层是不满的,这棵子树是一棵完全二叉树,它的节点数是左、右子树的节点数之和 + 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;
}
TreeNode left = root.left;
TreeNode right = root.right;
int leftCount = 0, rightCount =0;
while(left != null){
leftCount++;
left = left.left;
}
while(right != null){
rightCount++;
right = right.right;
}
if(leftCount == rightCount){
// 即2^leftCount -1
return (2 << leftCount) -1;
}
return countNodes(root.left) + countNodes(root.right) + 1;
}
}