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(广度优先搜索) 使用队列进行层序遍历是最直观的解法:

  1. 初始化队列,将根节点入队
  2. 逐层处理:记录当前层的节点数量
  3. 处理当前层的所有节点,同时将下一层的所有子节点入队
  4. 将当前层的节点值保存到结果中

方法二:DFS(深度优先搜索) 也可以用递归的方式实现,通过层级参数来标识当前深度:

  1. 递归访问每个节点,传递当前层级
  2. 根据层级将节点值添加到对应的结果数组中
  3. 递归访问所有子节点,层级加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)
DFSO(n)O(n)

其中 n 是树中节点的总数。空间复杂度主要来自队列或递归栈的开销,以及存储结果的空间。

相关题目