首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01 | 合格程序员的第一步:算法与数据结构
02 | 如何事半功倍地学习算法与数据结构
03 | 如何计算算法的复杂度
04 | 如何通过LeetCode来进行算法题目练习
05 | 理论讲解:数组&链表
06 | 面试题:反转一个单链表&判断链表是否有环
07 | 理论讲解:堆栈&队列
08 | 面试题:判断括号字符串是否有效
09 | 面试题:用队列实现栈&用栈实现队列
10 | 理论讲解:优先队列
11 | 面试题:返回数据流中的第K大元素
12 | 面试题:返回滑动窗口中的最大值
13 | 理论讲解:哈希表
14 | 面试题:有效的字母异位词
15 | 面试题:两数之和
16 | 面试题:三数之和
17 | 理论讲解:树&二叉树&二叉搜索树
18 | 面试题:验证二叉搜索树
19 | 面试题:二叉树&二叉搜索树的最近公共祖先
20 | 理论讲解:二叉树遍历
21 | 理论讲解:递归&分治
22 | 面试题:Pow(x,n)
23 | 面试题:求众数
24 | 理论讲解:贪心算法
25 | 面试题:买卖股票的最佳时机
26 | 理论讲解:广度优先搜索
27 | 理论讲解:深度优先搜索
28 | 面试题:二叉树层次遍历
29 | 面试题:二叉树的最大和最小深度
30 | 面试题:生成有效括号组合
31 | 理论讲解:剪枝
32 | 面试题:N皇后问题
33 | 面试题:数独问题
34 | 理论讲解:二分查找
35 | 面试题:实现一个求解平方根的函数
36 | 理论讲解:字典树
37 | 面试题:实现一个字典树
38 | 面试题:二维网格中的单词搜索问题
39 | 理论讲解:位运算
40 | 面试题:统计位1的个数
41 | 面试题:2的幂次方问题&比特位计数问题
42 | 面试题:N皇后问题的另一种解法
43 | 理论理解:动态规划(上)
44 | 理论理解:动态规划(下)
45 | 面试题:爬楼梯
46 | 面试题:三角形的最小路径和
47 | 面试题:乘积最大子序列
48 | 面试题:股票买卖系列
49 | 面试题:最长上升子序列
50 | 面试题:零钱兑换
51 | 面试题:编辑距离
52 | 理论讲解:并查集
53 | 面试题:岛屿的个数&朋友圈(上)
54 | 面试题:岛屿的个数&朋友圈(下)
55 | 理论讲解: LRU Cache
56 | 面试题:设计和实现一个LRU Cache缓存机制
57 | 理论讲解:布隆过滤器
当前位置:
首页>>
技术小册>>
算法面试通关 50 讲
小册名称:算法面试通关 50 讲
### 29 | 面试题:二叉树的最大和最小深度 在算法面试中,二叉树相关的问题是常见的考点之一,它们不仅考察了求职者对数据结构基础知识的掌握程度,还检验了其在递归、迭代等算法设计方面的能力。其中,“二叉树的最大和最小深度”问题是一个既经典又富有挑战性的问题,它要求我们在给定的二叉树中找出从根节点到最远叶子节点的最长路径(即最大深度)和最短路径(即最小深度,通常不考虑空树的情况)。下面,我们将详细探讨这一问题的解法,包括递归和迭代两种主要思路。 #### 一、问题定义 首先,明确问题的定义: - **二叉树的深度**:从根节点到最远叶子节点的最长路径上的节点数。 - **最大深度**:在二叉树中,所有路径中的最大深度。 - **最小深度**(非空树):在二叉树中,所有路径中的最小深度。注意,如果树为空,则深度讨论无意义;但在实际面试场景中,通常会假设树非空或明确说明如何处理空树的情况。 #### 二、递归解法 递归是解决二叉树深度问题的直观方法,因为它自然地反映了树的结构——将大问题分解为小问题。 ##### 2.1 最大深度 对于求最大深度,我们可以定义一个递归函数`maxDepth(TreeNode root)`,该函数检查当前节点是否为空: - 如果为空,返回0(因为空树没有深度)。 - 否则,递归地计算左子树和右子树的最大深度,然后取两者中的较大值加1(加1是因为要算上当前节点)。 ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def maxDepth(root): if not root: return 0 return max(maxDepth(root.left), maxDepth(root.right)) + 1 ``` ##### 2.2 最小深度 求最小深度时,需要注意到最小深度可能由单侧的子树决定(尤其是当另一侧为空时)。因此,递归函数`minDepth(TreeNode root)`需要稍作调整: - 如果为空,返回0(但在实际应用中,通常认为空树的最小深度无意义,这里仅为递归结束条件)。 - 如果只有一侧子树非空,返回该侧子树的最小深度加1。 - 如果两侧子树均非空,则返回两者中较小值加1。 ```python def minDepth(root): if not root: return 0 # 注意:实际使用中可能需要抛出异常或返回特定值表示空树 if not root.left: return minDepth(root.right) + 1 if not root.right: return minDepth(root.left) + 1 return min(minDepth(root.left), minDepth(root.right)) + 1 ``` #### 三、迭代解法 虽然递归解法直观且易于实现,但在处理深层递归时可能会遇到栈溢出的问题。迭代解法,尤其是利用栈(或队列,对于广度优先搜索BFS求最小深度)来模拟递归过程,可以有效避免这一问题。 ##### 3.1 最大深度(迭代,深度优先搜索DFS) 使用栈进行深度优先搜索(DFS)可以迭代地计算最大深度。算法流程如下: 1. 初始化一个栈和一个变量来记录当前深度。 2. 将根节点和初始深度(1)压入栈中。 3. 当栈不为空时,循环执行以下步骤: - 弹出栈顶元素(节点和当前深度)。 - 如果节点非空,更新最大深度(如果当前深度大于已知的最大深度)。 - 先右后左(或先左后右,取决于遍历顺序)将子节点和当前深度加1压入栈中。 ```python def maxDepthIterative(root): if not root: return 0 stack, max_depth = [(root, 1)], 0 while stack: node, depth = stack.pop() if node: max_depth = max(max_depth, depth) if node.right: stack.append((node.right, depth + 1)) if node.left: # 注意先右后左是为了保证先遍历到最深的节点 stack.append((node.left, depth + 1)) return max_depth ``` ##### 3.2 最小深度(迭代,广度优先搜索BFS) 求最小深度时,广度优先搜索(BFS)是更自然的选择,因为它能逐层遍历树,直到找到第一个叶子节点。算法流程如下: 1. 初始化一个队列和一个变量来记录当前层数。 2. 将根节点和层数0(实际上从1开始计数,但为了方便计算,可以用层数变化来表示)加入队列。 3. 当队列不为空时,循环执行以下步骤: - 弹出队列首元素(节点和当前层数)。 - 如果节点是叶子节点,返回当前层数加1。 - 否则,将非空子节点和当前层数加1加入队列。 ```python from collections import deque def minDepthIterative(root): if not root: return 0 # 实际上,对于非空树的最小深度问题,这里应返回错误信息或特定值 queue = deque([(root, 1)]) # (node, level) while queue: node, level = queue.popleft() if not node.left and not node.right: return level if node.left: queue.append((node.left, level + 1)) if node.right: queue.append((node.right, level + 1)) # 理论上不会执行到这里,除非输入为空树且未处理空树情况 return -1 # 返回一个不可能的值表示错误或异常情况 ``` #### 四、总结 通过本章节的学习,我们深入探讨了二叉树的最大和最小深度的计算方法,包括递归和迭代两种解法。递归解法直观易懂,但在处理深层树时可能遇到栈溢出的问题;迭代解法,特别是使用栈的DFS和队列的BFS,提供了更稳健的解决方案。掌握这些解法不仅有助于应对面试中的相关问题,也是深入理解二叉树结构和算法设计的重要一步。
上一篇:
28 | 面试题:二叉树层次遍历
下一篇:
30 | 面试题:生成有效括号组合
该分类下的相关小册推荐:
数据结构与算法之美
数据结构与算法(上)
编程之道-算法面试(上)
数据结构与算法(中)
业务开发实用算法精讲
编程之道-算法面试(下)
数据结构与算法(下)