Medium
题目描述
给定一个 N 叉树,返回其节点值的层序遍历。
N 叉树的输入序列化是用层序遍历表示的,每组子节点之间用 null 值分隔(见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14]
输出:[[1],[2,3,4,5],[6,7,8,9,10],[11,12,13],[14]]
提示:
- 树的高度不会超过 1000
- 树的节点总数在范围 [0, 10^4] 内
解题思路
这是一道经典的树的层序遍历问题,核心是按层级顺序访问所有节点。
方法一:BFS(广度优先搜索) 使用队列进行层序遍历是最直观的解法:
- 初始化队列,将根节点入队
- 逐层处理:记录当前层的节点数量
- 处理当前层的所有节点,同时将下一层的所有子节点入队
- 将当前层的节点值保存到结果中
方法二:DFS(深度优先搜索) 也可以用递归的方式实现,通过层级参数来标识当前深度:
- 递归访问每个节点,传递当前层级
- 根据层级将节点值添加到对应的结果数组中
- 递归访问所有子节点,层级加1
两种方法的时间复杂度都是 O(n),空间复杂度也都是 O(n)。BFS 方法更直观易懂,是推荐解法。DFS 方法在某些场景下可能有栈溢出的风险,但代码更简洁。
代码实现
/*
// Definition for a Node.
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:
vector<vector<int>> levelOrder(Node* root) {
vector<vector<int>> result;
if (!root) return result;
queue<Node*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
vector<int> level;
for (int i = 0; i < size; i++) {
Node* node = q.front();
q.pop();
level.push_back(node->val);
for (Node* child : node->children) {
q.push(child);
}
}
result.push_back(level);
}
return result;
}
};
"""
# Definition for a Node.
class Node:
def __init__(self, val: Optional[int] = None, children: Optional[List['Node']] = None):
self.val = val
self.children = children
"""
class Solution:
def levelOrder(self, root: 'Node') -> List[List[int]]:
if not root:
return []
result = []
queue = [root]
while queue:
level_size = len(queue)
level = []
for _ in range(level_size):
node = queue.pop(0)
level.append(node.val)
if node.children:
queue.extend(node.children)
result.append(level)
return result
/*
// Definition for a Node.
public class Node {
public int val;
public IList<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, IList<Node> _children) {
val = _val;
children = _children;
}
}
*/
public class Solution {
public IList<IList<int>> LevelOrder(Node root) {
IList<IList<int>> result = new List<IList<int>>();
if (root == null) return result;
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
while (queue.Count > 0) {
int size = queue.Count;
IList<int> level = new List<int>();
for (int i = 0; i < size; i++) {
Node node = queue.Dequeue();
level.Add(node.val);
if (node.children != null) {
foreach (Node child in node.children) {
queue.Enqueue(child);
}
}
}
result.Add(level);
}
return result;
}
}
/**
* // Definition for a _Node.
* function _Node(val,children) {
* this.val = val;
* this.children = children;
* };
*/
/**
* @param {_Node|null} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (!root) return [];
const result = [];
const queue = [root];
while (queue.length > 0) {
const levelSize = queue.length;
const level = [];
for (let i = 0; i < levelSize; i++) {
const node = queue.shift();
level.push(node.val);
if (node.children) {
queue.push(...node.children);
}
}
result.push(level);
}
return result;
};
复杂度分析
| 方法 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| BFS(推荐) | O(n) | O(n) |
| DFS | O(n) | O(n) |
其中 n 是树中节点的总数。空间复杂度主要来自队列或递归栈的开销,以及存储结果的空间。