死磕算法系列文章
- 干货 | 手撕十大经典排序算法
- 剑指offer | 认识面试
- 剑指offer | 面试题2:实现Singleton模式
- 剑指offer | 面试题3:二维数组的查找
- 剑指offer | 面试题4:替换空格
- 剑指offer | 面试题5:从尾到头打印链表
- 剑指offer | 面试题6:重建二叉树
- 剑指offer | 面试题7:用两个栈实现队列
- 剑指offer | 面试题8:旋转数组的最小数字
- 剑指offer | 面试题9:斐波那契数列
- 剑指offer | 面试题10:青蛙跳台阶问题
- 剑指offer | 面试题11:矩阵覆盖
- 剑指offer | 面试题12:二进制中1的个数
- 剑指offer | 面试题13:数值的整数次方
- 剑指offer | 面试题14:打印从1到最大的n位数
- 剑指offer | 面试题15:删除链表的节点
- 剑指offer | 面试题16:将数组中的奇数放在偶数前
- 剑指offer | 面试题17:链表中倒数第k个节点
- 剑指offer | 面试题18:反转链表
- 剑指offer | 面试题19:合并两个有序链表
- 剑指offer | 面试题20:判断二叉树A中是否包含子树B
- 剑指offer | 面试题21:二叉树的镜像
- 剑指offer | 面试题22:顺时针打印矩阵
- 剑指offer | 面试题23:包含min函数的栈
- 剑指offer | 面试题24:栈的压入、弹出序列
- 剑指offer | 面试题25:从上到下打印二叉树
- 剑指offer | 面试题26:二叉搜索树的后序遍历序列
- 剑指offer | 面试题27:二叉树中和为某一值的路径
- 剑指offer | 面试题28:复杂链表的复制
- 剑指offer | 面试题29:二叉搜索树转换为双向链表
- 剑指offer | 面试题30:字符串的排列
- 剑指offer | 面试题31:数组中出现次数超过一半的数字
- 剑指offer | 面试题32:最小的k个数
- 剑指offer | 面试题33:连续子数组的最大和
- 剑指offer | 面试题34:1~n 整数中 1 出现的次数
- 剑指offer | 面试题35:把数组排成最小的数
- 剑指offer | 面试题36:丑数
- 剑指offer | 面试题37:第一个只出现一次的字符
- 剑指offer | 面试题38:数组中的逆序对
- 剑指offer | 面试题39:两个链表的第一个公共节点
- 剑指offer | 面试题40:数组中数字出现的次数
“Leetcode : https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/
“GitHub : https://github.com/nateshao/leetcode/blob/main/algo-notes/src/main/java/com/nateshao/sword_offer/topic_41_maxDepth/Solution.java
剑指 Offer 55 - I. 二叉树的深度
代码语言:javascript复制“题目描述 :输入一棵二叉树的根节点,求该树的深度。从根节点到叶节点依次经过的节点(含根、叶节点)形成树的一条路径,最长路径的长度为树的深度。 难度:简单
例如:给定二叉树 [3,9,20,null,null,15,7],
3
/
9 20
/
15 7
返回它的最大深度 3 。
方法一:递归 (后序遍历)
“树的遍历方式总体分为两类:深度优先搜索(DFS)、广度优先搜索(BFS);
- 常见的 DFS : 先序遍历、中序遍历、后序遍历(左右根);
- 常见的 BFS : 层序遍历(即按层遍历)。
- 树的后序遍历 / 深度优先搜索往往利用 递归 或 栈 实现
- 关键点: 此树的深度和其左(右)子树的深度之间的关系。显然,此树的深度 等于 左子树的深度 与 右子树的深度 中的 最大值 1 。
算法解析:
- 终止条件: 当
root
为空,说明已越过叶节点,因此返回 深度 0 。 - 递推工作:本质上是对树做后序遍历。
- 计算节点 root 的 左子树的深度 ,即调用 maxDepth(root.left);
- 计算节点 root 的 右子树的深度 ,即调用 maxDepth(root.right);
- 返回值: 返回 此树的深度 ,即
max(maxDepth(root.left), maxDepth(root.right)) 1
。
- In other words, 考虑以下几种情况: 如果二叉树为空,深度为 0;如果二叉树只有根节点,深度为 1;如果二叉树的根节点只有左子树,深度为左子树的深度加 1;如果二叉树的根节点只有右子树,深度为右子树的深度加 1;如果二叉树的根节点既有左子树又有右子树,深度为左右子树深度的最大者再加 1。
复杂度分析:
- 时间复杂度 O(N):N 为树的节点数量,计算树的深度需要遍历所有节点。
- 空间复杂度 O(N) :最差情况下(当树退化为链表时),递归深度可达到 N 。
package com.nateshao.one_question_per_day.code_2022.january;
/**
* @date Created by 邵桐杰 on 2022/1/22 22:56
* @微信公众号 千羽的编程时光
* @个人网站 www.nateshao.cn
* @博客 https://nateshao.gitee.io
* @GitHub https://github.com/nateshao
* @Gitee https://gitee.com/nateshao
* Description:
*/
public class Solution_2022_01_22_maxDepth {
/**
* 方法一:递归解法
* 思路:利用递归遍历分别返回左右子树深度
*
* @param root
* @return
*/
public int maxDepth(TreeNode root) {
// return root == null ? 0 : Math.max(maxDepth(root.left), maxDepth(root.right) 1);
if (root == null) return 0;
int left = maxDepth(root.left);
int right = maxDepth(root.right);
return Math.max(left, right) 1;
}
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
}
Golang
代码语言:javascript复制/* go 语言没有三目运算符 */
func maxDepth(root *TreeNode) int {
if root == nil {
return 0
}
return max(maxDepth(root.Left), maxDepth(root.Right)) 1
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
方法二:非递归一一层序遍历(BFS)
- 树的层序遍历 / 广度优先搜索往往利用 队列 实现。
- 关键点: 每遍历一层,则计数器 1 ,直到遍历完成,则可得到树的深度。
算法解析:
- 特例处理: 当
root
为空,直接返回 深度 0 。 - 初始化: 队列
queue
(加入根节点root
),计数器res = 0
。 - 循环遍历: 当
queue
为空时跳出。- 初始化一个空列表
tmp
,用于临时存储下一层节点; - 遍历队列:遍历
queue
中的各节点node
,并将其左子节点和右子节点加入tmp
; - 更新队列:执行
queue = tmp
,将下一层节点赋值给queue
; - 统计层数:执行
res = 1
,代表层数加 1;
- 初始化一个空列表
/**
* 方法二:层序遍历(BFS)
* @param root
* @return
*/
public int maxDepth2(TreeNode root) {
if (root == null) return 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
int res = 0;
while (!queue.isEmpty()) {
res ;
int n = queue.size();
for (int i = 0; i < n; i ) {
TreeNode node = queue.poll();
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
}
return res;
}
Golang
代码语言:javascript复制/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func maxDepth(root *TreeNode) int {
// 边界
if root == nil {
return 0
}
depth := 0
var queue []*TreeNode
queue = append(queue, root)
// bfs
for len(queue) > 0 {
length := len(queue)
for i := 0; i < length; i {
cur := queue[0]
queue = queue[1:]
if cur.Left != nil {
queue = append(queue, cur.Left)
}
if cur.Right != nil {
queue = append(queue, cur.Right)
}
}
depth = 1
}
return depth
}
参考链接:
- https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/mian-shi-ti-55-i-er-cha-shu-de-shen-du-xian-xu-bia/
- https://leetcode-cn.com/problems/er-cha-shu-de-shen-du-lcof/solution/jian-zhi-offer-55-i-er-cha-shu-de-shen-du-di-gui-c/