LeetCode 559简单树 · BST
N 叉树的最大深度 图解题解
这道题到底在问什么
给定一棵 N 叉树的根 root,返回它的最大深度。最大深度 = 从根节点到最远叶子节点的最长路径上的节点总数。空树深度为 0,单个节点深度为 1。
- 输入
- root = [50,[30,[10,20],80,[60]]]
- 输出
- 3
最优解:一步一步想明白
- 3记牢「先算孩子、取最大、加一层」,下面每一帧都在套它。
- 4目标:算出根 50 的子树深度先看整棵树。我们要算根 50 的子树深度。办法是从根往下递归:先把每个孩子的子树深度都算清楚,再取最大、加上自己这一层。下面跟着紫色的「当前节点」一路下探。
- 550 有 2 个孩子走到节点 50(紫色)。它的孩子列表有 2 个:30、80。想知道 50 的深度,得先把这几个孩子的子树深度逐个算出来。
- 6先深入孩子 30按后序的规矩,先把第一个孩子 30 的子树彻底算完,再回头看 50 剩下的孩子。我们顺着这条边往下走。
- 730 有 2 个孩子走到节点 30(紫色)。它的孩子列表有 2 个:10、20。想知道 30 的深度,得先把这几个孩子的子树深度逐个算出来。
- 8先深入孩子 10按后序的规矩,先把第一个孩子 10 的子树彻底算完,再回头看 30 剩下的孩子。我们顺着这条边往下走。
- 910 没有孩子走到节点 10(紫色)。它的孩子列表是空的,是个叶子,不用再往下了。
- 1010 子树深度 1叶子 10 没有孩子,最深孩子算 0,加上自己这一层,子树深度就是 1。节点 10 标绿,表示它的深度已经定下来了。
- 11还剩 1 个孩子孩子 10 那一支已经算完(深度 1),回到 30。它还有孩子没算,接着深入下一个 20。
- 1220 没有孩子走到节点 20(紫色)。它的孩子列表是空的,是个叶子,不用再往下了。
- 1320 子树深度 1叶子 20 没有孩子,最深孩子算 0,加上自己这一层,子树深度就是 1。节点 20 标绿,表示它的深度已经定下来了。
- 14孩子深度 1、1,最大 130 的孩子都算完了,子树深度分别是 1、1。我们要的是最深的那个,取最大值得到 1。正在判定 30,先别急着定色。
- 1530 子树深度 2最深的孩子子树是 1,加上 30 自己这一层,30 的子树深度 = 1 + 1 = 2。节点 30 标绿,深度敲定。
- 16还剩 1 个孩子孩子 30 那一支已经算完(深度 2),回到 50。它还有孩子没算,接着深入下一个 80。
- 1780 有 1 个孩子走到节点 80(紫色)。它的孩子列表有 1 个:60。想知道 80 的深度,得先把这几个孩子的子树深度逐个算出来。
- 18先深入孩子 60按后序的规矩,先把第一个孩子 60 的子树彻底算完,再回头看 80 剩下的孩子。我们顺着这条边往下走。
- 1960 没有孩子走到节点 60(紫色)。它的孩子列表是空的,是个叶子,不用再往下了。
- 2060 子树深度 1叶子 60 没有孩子,最深孩子算 0,加上自己这一层,子树深度就是 1。节点 60 标绿,表示它的深度已经定下来了。
- 21孩子深度 1,最大 180 的孩子都算完了,子树深度分别是 1。我们要的是最深的那个,取最大值得到 1。正在判定 80,先别急着定色。
- 2280 子树深度 2最深的孩子子树是 1,加上 80 自己这一层,80 的子树深度 = 1 + 1 = 2。节点 80 标绿,深度敲定。
- 23孩子深度 2、2,最大 250 的孩子都算完了,子树深度分别是 2、2。我们要的是最深的那个,取最大值得到 2。正在判定 50,先别急着定色。
- 2450 子树深度 3最深的孩子子树是 2,加上 50 自己这一层,50 的子树深度 = 1 + 2 = 3。节点 50 标绿,深度敲定。
- 25最大深度 = 3所有节点都结算完了。根 50 的两个孩子 30 和 80 子树深度都是 2,取最大 2 再加 1,根的子树深度就是 3。这正是从根到最远叶子那条路上的节点数,答案 = 3。
⚠️ 容易写错的地方
✗ 错:空节点返回 1
✓ 对:空节点应返回 0
深度是节点数,空树没有节点,必须是 0,否则整棵树会多算一层
✗ 错:只递归第一个孩子
✓ 对:要遍历全部孩子取最大
N 叉树孩子是列表,漏掉任何一个孩子都可能错过最深的那条路
✗ 错:用「孩子深度之和」
✓ 对:是取最大不是求和
深度看的是最长一条路径,不是所有分支加起来
完整代码(Python / C++ / Java)
Python
from typing import List
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children if children is not None else []
class Solution:
def maxDepth(self, root: 'Node') -> int:
if not root:
return 0
return 1 + max([self.maxDepth(c) for c in root.children] or [0])C++
#include <algorithm>
#include <functional>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
class Node {
public:
int val;
vector<Node*> children;
Node() {}
Node(int _val) { val = _val; }
Node(int _val, vector<Node*> _children) { val = _val; children = _children; }
};
class Solution {
public:
int maxDepth(Node* root) {
if (!root) return 0;
int best = 0;
for (Node* child : root->children) best = max(best, maxDepth(child));
return best + 1;
}
};Java
import java.util.*;
class Node {
public int val;
public List<Node> children;
public Node() { children = new ArrayList<>(); }
public Node(int _val) { val = _val; children = new ArrayList<>(); }
public Node(int _val, List<Node> _children) { val = _val; children = _children; }
}
class Solution {
public int maxDepth(Node root) {
if (root == null) return 0;
int best = 0;
for (Node child : root.children) best = Math.max(best, maxDepth(child));
return best + 1;
}
}复杂度
时间
O(n)
每个节点恰好被访问一次,做的都是常数工作(取最大、加一),n 是节点总数
空间
O(h)
递归栈深度等于树高 h;最坏退化成一条链时 h 可达 n
看不够?换成动画再走一遍
上面的推演每一步都对应一帧动画。点开交互动画版,能一步步看着 N 叉树的最大深度 的数据怎么变、指针怎么走,还能切 Python / Java / C++ 跟着练。
面试官可能追问
这题和二叉树最大深度(LeetCode 104)有什么区别?+
思路完全一样,都是「1 加上孩子里最深的子树」。区别只在二叉树固定左右两个孩子,写成 1 加 max(左, 右);N 叉树孩子个数不定,是一个列表,要用循环或遍历对所有孩子取最大。本质同一套后序递归。
能不能不用递归,改成迭代?+
可以。用广度优先一层层往下数层数:每弹出一层所有节点、把它们的孩子全部入队,层数加 1,队列空时层数就是深度。也可以用栈做显式 DFS,给每个节点带上它所在的深度,过程中维护一个最大值。面试里讲清递归思路,再补一句迭代方案即可。
想听吴师兄把这道题讲给你听?
文字版和动画都随便看。开通图解算法年卡,可以听吴师兄声线把 N 叉树的最大深度 一步步讲透(全站 0 节语音精讲,持续扩充), 卡住的地方还有 AI 私教小欧就着动画帮你拆到懂。
本平台为独立第三方培训机构,与华为技术有限公司无任何关联;课程的服务内容与权益以购买协议为准,学习效果因个人情况而异。「华为 OD」「华为可信」等仅为对岗位与考试方向的客观描述,相关商标归各自权利人所有。