1. 引言
在二叉树的基础问题中,计算二叉树的最大深度 是一个常见的问题。最大深度定义为:
从根节点到最远叶子节点的最长路径上的节点数。
本篇文章将详细讲解该问题的解法,并提供相关知识点,包括 递归解法、迭代解法 及其 时间复杂度分析。
2. 递归解法(深度优先搜索 DFS)
2.1 递归思想
我们可以使用 递归 来求解最大深度:
- 若树为空(即
root == nullptr
),返回0
。 - 递归计算左子树
maxDepth(root->left)
。 - 递归计算右子树
maxDepth(root->right)
。 - 取左右子树的最大值,并加
1
作为当前节点的深度。
2.2 代码实现
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) {
return 0;
}
int leftDepth = maxDepth(root->left);
int rightDepth = maxDepth(root->right);
return max(leftDepth, rightDepth) + 1;
}
};
2.3 时间和空间复杂度分析
- 时间复杂度: 由于需要遍历每个节点一次,时间复杂度为 O(N),其中
N
为节点数。 - 空间复杂度: 由于递归调用栈的深度最坏情况下可能达到
O(N)
(退化成链表),平均情况下为O(log N)
(平衡二叉树)。
3. 迭代解法(广度优先搜索 BFS)
3.1 迭代思想
我们也可以使用 广度优先搜索(BFS) 通过层序遍历计算最大深度:
- 使用
queue
进行层次遍历,每遍历一层,深度+1
。 - 遍历当前层的所有节点,并将其子节点加入队列。
- 继续处理下一层,直到队列为空。
3.2 代码实现
#include <queue>
using namespace std;
class Solution {
public:
int maxDepth(TreeNode* root) {
if (!root) return 0;
queue<TreeNode*> q;
q.push(root);
int depth = 0;
while (!q.empty()) {
int size = q.size();
for (int i = 0; i < size; i++) {
TreeNode* node = q.front(); q.pop();
if (node->left) q.push(node->left);
if (node->right) q.push(node->right);
}
depth++;
}
return depth;
}
};
3.3 时间和空间复杂度分析
- 时间复杂度:
O(N)
,所有节点都会被访问一次。 - 空间复杂度:
O(N)
,最坏情况下(完全二叉树的最后一层)队列存储N/2
个节点。
4. 递归与迭代的对比
方法 | 递归(DFS) | 迭代(BFS) |
---|---|---|
适用情况 | 适用于树较深但递归不会导致栈溢出的情况 | 适用于层序遍历或避免递归栈溢出的情况 |
时间复杂度 | O(N) | O(N) |
空间复杂度 | O(log N)(平衡树),最坏 O(N) | O(N)(最坏情况下存储最后一层的所有节点) |
5. 总结
- 递归方法(DFS) 适用于大多数情况,代码简洁直观,但深度过深时可能栈溢出。
- 迭代方法(BFS) 使用
queue
层序遍历,每层处理一次,适用于避免递归栈溢出的情况。
如果你正在准备 LeetCode 或 面试,建议两种方法都掌握,以便根据不同情况选择合适的方法!
希望本篇文章对你有所帮助,欢迎讨论更多关于二叉树的问题!