面试经典算法23- 二叉树的最大深度
LeetCode.104
公众号:阿Q技术站
问题描述
给定一个二叉树 root
,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7]
输出:3
示例 2:
输入:root = [1,null,2]
输出:2
提示:
- 树中节点的数量在
[0, 104]
区间内。 -100 <= Node.val <= 100
思路
递归(深度优先搜索)
- 使用深度优先搜索(DFS)的方式遍历二叉树。
- 递归计算左右子树的最大深度,取其中较大值加上当前节点的深度作为当前节点所在子树的最大深度。
- 初始时,根节点的深度为1。
非递归(广度优先搜索)
- 使用一个队列来存储每一层的节点。
- 将根节点入队。
- 进入循环,每次循环处理一层的节点。首先记录当前队列的大小,表示当前层的节点个数。
- 在内部循环中,依次从队列中取出节点,并将其左右子节点(如果存在)入队。
- 内部循环结束后,表示当前层的节点已经处理完毕,深度加1。
- 外部循环继续直到队列为空,此时遍历完所有层,返回深度作为结果。
图解
递归
- 从根节点3开始进行递归
- 递归根节点3的左子树,即节点9
- 向上返回左子树9的深度,max(0,0) + 1 = 1.
- 递归根节点3的右子树,即节点20。
- 递归节点20的左子树,即节点15.
- 向上返回节点15的深度,max(0,0) + 1 = 1.
- 递归20的右子树,即节点7.
- 向上返回节点7的深度,max(0,0) + 1 = 1.
- 向上返回节点20的深度,max(1,1) + 1 = 2.
- 向上返回根节点3的深度,max(1,2) + 1 = 3.
非递归
- 初始化深度为0,并遍历第一层,即:将根节点push到队列中。
-
从队列中取出一个节点,该节点是当前层待处理的节点之一。然后,从队列中移除这个节点,因为我们已经处理过它了。将当前节点的左右子节点(如果存在)加入到队列中,以便后续处理它们。
-
当第一层遍历完时,depth++,此时depth=1,并开始遍历第二层。
- 当第二层遍历完时,depth++,此时depth=2,开始遍历第三层。
- 当第三层遍历完时,depth++,此时depth=3,队列也为空了,就退出循环,返回depth。
参考代码
C++
递归
#include <iostream>
#include <algorithm>
// 二叉树节点的定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) {
return 0; // 空节点深度为0
}
// 递归计算左右子树的最大深度,加上当前节点的深度1
return std::max(maxDepth(root->left), maxDepth(root->right)) + 1;
}
};
// 创建二叉树
TreeNode* createBinaryTree(std::vector<int>& nums, int index) {
if (index >= nums.size() || nums[index] == -1) {
return nullptr; // 如果节点值为-1表示为空节点
}
TreeNode* root = new TreeNode(nums[index]);
root->left = createBinaryTree(nums, 2 * index + 1); // 左子树节点索引为2*i+1
root->right = createBinaryTree(nums, 2 * index + 2); // 右子树节点索引为2*i+2
return root;
}
// 输出二叉树
void printBinaryTree(TreeNode* root) {
if (root == nullptr) {
return;
}
std::cout << root->val << " ";
printBinaryTree(root->left);
printBinaryTree(root->right);
}
int main() {
std::vector<int> nums = {3, 9, 20, -1, -1, 15, 7}; // 示例输入数组
TreeNode* root = createBinaryTree(nums, 0); // 创建二叉树
Solution solution;
int depth = solution.maxDepth(root); // 计算最大深度
std::cout << "二叉树的最大深度为: " << depth << std::endl; // 输出结果
return 0;
}
非递归
#include <iostream>
#include <queue>
#include <algorithm>
// 二叉树节点的定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
class Solution {
public:
int maxDepth(TreeNode* root) {
if (root == nullptr) {
return 0;
}
int depth = 0;
std::queue<TreeNode*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
while (size > 0) {
TreeNode* node = q.front();
q.pop();
if (node->left != nullptr) {
q.push(node->left);
}
if (node->right != nullptr) {
q.push(node->right);
}
size--;
}
depth++; // 每遍历一层,深度加1
}
return depth;
}
};
// 创建二叉树
TreeNode* createBinaryTree(std::vector<int>& nums, int index) {
if (index >= nums.size() || nums[index] == -1) {
return nullptr; // 如果节点值为-1表示为空节点
}
TreeNode* root = new TreeNode(nums[index]);
root->left = createBinaryTree(nums, 2 * index + 1); // 左子树节点索引为2*i+1
root->right = createBinaryTree(nums, 2 * index + 2); // 右子树节点索引为2*i+2
return root;
}
// 输出二叉树
void printBinaryTree(TreeNode* root) {
if (root == nullptr) {
return;
}
std::cout << root->val << " ";
printBinaryTree(root->left);
printBinaryTree(root->right);
}
int main() {
std::vector<int> nums = {3, 9, 20, -1, -1, 15, 7}; // 示例输入数组
TreeNode* root = createBinaryTree(nums, 0); // 创建二叉树
Solution solution;
int depth = solution.maxDepth(root); // 计算最大深度
std::cout << "二叉树的最大深度为: " << depth << std::endl; // 输出结果
return 0;
}
Java
import java.util.LinkedList;
import java.util.Queue;
// 二叉树节点的定义
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
public class Solution {
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
// 使用队列存储每一层的节点
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int depth = 0;
// 循环处理每一层的节点
while (!queue.isEmpty()) {
int size = queue.size(); // 当前层的节点个数
depth++; // 深度加1
// 处理当前层的节点
for (int i = 0; i < size; i++) {
TreeNode node = queue.poll();
// 将当前节点的左右子节点(如果存在)加入队列
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}
return depth; // 返回最大深度
}
// 创建二叉树
public static TreeNode createTree(Integer[] array, int index) {
TreeNode root = null;
if (index < array.length) {
Integer value = array[index];
if (value == null) {
return null;
}
root = new TreeNode(value);
root.left = createTree(array, 2 * index + 1);
root.right = createTree(array, 2 * index + 2);
}
return root;
}
public static void main(String[] args) {
Integer[] array = {3, 9, 20, null, null, 15, 7};
TreeNode root = createTree(array, 0);
Solution solution = new Solution();
int depth = solution.maxDepth(root);
System.out.println("二叉树的最大深度为:" + depth);
}
}
Python版本
# 二叉树节点的定义
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:
return 0
queue = [root] # 使用列表模拟队列存储每一层的节点
depth = 0
while queue:
size = len(queue) # 当前层的节点个数
depth += 1 # 深度加1
# 处理当前层的节点
for _ in range(size):
node = queue.pop(0)
# 将当前节点的左右子节点(如果存在)加入队列
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return depth # 返回最大深度
# 创建二叉树
def create_tree(array, index):
if index < len(array):
value = array[index]
if value is None:
return None
root = TreeNode(value)
root.left = create_tree(array, 2 * index + 1)
root.right = create_tree(array, 2 * index + 2)
return root
return None
array = [3, 9, 20, None, None, 15, 7]
root = create_tree(array, 0)
solution = Solution()
depth = solution.maxDepth(root)
print("二叉树的最大深度为:", depth)