day16 二叉树 part3
day16-1 104.二叉树的最大深度
- 编码耗时:00:03:21
什么是深度和高度
深度:任意一个节点到根节点的距离
高度:任意一个节点到叶子节点的距离
求高度有后序遍历,从下往上计数;求深度用前序遍历,从上往下计数
确定遍历顺序
求高度用后序遍历:左右中,将下一次的高度放回给上一层的父子节点,父节点再做加一操作,让后就知道自己的高度了
求深度用中序遍历:往下遍历一个就加一,符号求深度的过程
为什么求根节点的高度就能求出二叉树的最大深度:二叉树的高度就是其最大深度
代码实现
/**
* 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) {
// Queue<TreeNode> que = new LinkedList();
// int depth = 0;
// if(root == null){
// return 0;
// }
// que.add(root);
// while(!que.isEmpty()){
// int size = que.size();
// while(size > 0){
// TreeNode tempNode = que.poll();
// if(tempNode.left != null){
// que.add(tempNode.left);
// }
// if(tempNode.right != null){
// que.add(tempNode.right);
// }
// size --;
// }
// depth++;
// }
// return depth;
// }
// 二叉树的最大高度 后序遍历
public int maxDepth(TreeNode root) {
return getheight(root);
}
private int getheight(TreeNode root){
if(root == null){
return 0;
}
int leftHeight = getheight(root.left);
int rightHeigt = getheight(root.right);
return 1 + Math.max(leftHeight, rightHeigt);
}
}
day16-2 559.n叉树的最大深度
- 两种方法编码通过耗时:00:15:01
/*
// 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;
// }
// int depth = 0;
// if(root.children != null){
// for(Node child : root.children){
// depth = Math.max(depth, maxDepth(child)); // 求孩子中拥有的最大深度
// }
// }
// return depth + 1;
// }
/**
* 迭代法 层序遍历
*/
public int maxDepth(Node root) {
Queue<Node> que = new LinkedList();
int depth = 0;
if(root == null){
return 0;
}
que.offer(root);
while(!que.isEmpty()){
int size = que.size();
while(size > 0){
Node tempNode = que.poll();
for(Node node: tempNode.children){
if(node != null){
que.offer(node);
}
}
size --;
}
depth++;
}
return depth;
}
}
day 16-3 111.二叉树的最小深度(注意代码误区)
- 编码通过耗时: 00: 25:00 —>写错单词把left写成right导出出错,调错花了点时间
和最大深度的区别
最小深度:根节点到最近叶子结点的距离
遍历顺序
后序遍历:左右中
代码实现
代码误区
根结点左为空右不为空的情况
如果return时,使用return 1+min(rightheight, leftheight);
/**
* 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) {
// Queue<TreeNode> que = new LinkedList();
// int depth = 0;
// if(root == null){
// return depth;
// }
// que.add(root);
// while(!que.isEmpty()){
// int size = que.size();
// depth++;
// while(size > 0){
// TreeNode tempNode = que.poll();
// // 当当前节点的左右孩子都为空,直接返回最小深度
// if( tempNode.left == null && tempNode.right == null){
// return depth;
// }
// if(tempNode.left != null){
// que.add(tempNode.left);
// }
// if(tempNode.right != null){
// que.add(tempNode.right);
// }
// size--;
// }
// }
// return depth;
// }
// 最小深度 递归 后序遍历求最小高度从而得到最小
public int minDepth(TreeNode root) {
return getHeight(root);
}
private int getHeight(TreeNode root){
if(root == null){
return 0;
}
// 左
int leftHeight = getHeight(root.left);
// 右
int rightHeight = getHeight(root.right);
// 中 要稍微处理一下代码来符号最小深度的定义:最小深度的定义为从**根节点**到**最近叶子结点**的最短路径。
if(root.left == null && root.right != null){
return rightHeight +1;
}
if(root.left != null && root.right == null){
return leftHeight + 1 ;
}
return Math.min(leftHeight, rightHeight) + 1;
}
}
day 16-4 222.完全二叉树的节点个数(注意是完全二叉树 递归 后序代码少)
- 编码通过耗时:00:10:05
普通二叉树的解法
递归,后序遍历写的代码要简单点,时间复杂度为O(n)
完全二叉树的思路
利用公式:2^(n-1)-1 n为深度
代码实现
/**
* 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;
// }
// // 后序遍历
// // 左
// int leftNum = countNodes(root.left);
// // 右
// int rightNum = countNodes(root.right);
// // 中
// return leftNum + rightNum + 1;
// }
// 递归 后序遍历 满二叉树思路
public int countNodes(TreeNode root) {
if(root == null){
return 0;
}
TreeNode left = root.left;
TreeNode right = right = root.right;
int leftDepth = 0, rightDepth = 0;
// 检查是否是完全二叉树,如果是直接用公式计算 2^(n-1) -1 其中n表示为深度
while(left != null){
left = left.left;
leftDepth++;
}
while(right != null){
right = right.right;
rightDepth++;
}
if(rightDepth == leftDepth){
return (2<<leftDepth) - 1;
}
int leftNum = countNodes(root.left);
int rightNum = countNodes(root.right);
return leftNum + rightNum + 1;
}
}
总结
- 总耗时:3h