429. 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]]
链接
https://leetcode.cn/problems/n-ary-tree-level-order-traversal/
解题思路
思路一: 广度优先遍历
- 首先把根节点 root 放入队列中,随后在广度优先搜索的每一轮中,我们首先记录下当前队列中包含的节点个数(记为 len),即表示上一层的节点个数。
- 在这之后,我们从队列中依次取出节点,直到取出了上一层的全部 len 个节点为止。当取出节点 node 时,我们将 node 的值放入一个临时列表,再将 node 的所有子节点全部放入队列中。
当这一轮遍历完成后,临时列表中就存放了当前层所有节点的值。这样一来,当整个广度优先搜索完成后,我们就可以得到层序遍历的结果
/**
* @param {Node|null} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (root == null) return [];
let res = [], queue = [root];
while(queue.length) {
let len = queue.length, curLevel = [];
while(len--) {
let node = queue.shift();
curLevel.push(node.val);
// 这里不再是 ndoe.left node.right 而是循坏node.children
for (let item of node.children) {
item && queue.push(item)
}
}
res.push(curLevel);
}
return res;
};
时间复杂度: O(n), 其中 n 是二叉树的节点数
空间复杂度: O(n)
思路二: 深度优先搜索
使用一个临时变量(如「哈希表」)存储每个深度 depth 对应的节点列表,当处理到节点 node 时,将其值添加到其所在的深度列表中。
同时在 DFS 过程中记录下最大深度 max,跑完 DFS 后,根据 max 来构建答案
实现代码如下:
/**
* @param {Node|null} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (root == null) return [];
let max = 0, obj = {}, res = [];
const dfs = function (node, depth) {
max = Math.max(max, depth);
let arr = obj[depth] || [];
arr.push(node.val);
obj[depth] = arr;
for (let item of node.children) item && dfs(item, depth + 1);
}
dfs(root, 0);
for (let i = 0; i <= max; i++) res.push(obj[i]);
return res;
}
时间复杂度: O(n), 其中 n 是二叉树的节点数
空间复杂度: O(n)
优化: 不使用临时变量存储每个深度 depth 对应的节点列表, 每次访问深度为 depth 的层级的时候,先检查 res 是否存在下标为 depth 的位置,若没有,说明是首次访问 depth 层(depth 层的最左侧元素),此时将该位置创建出来,再把当前节点值 node 添加到 res[depth] 中
实现代码如下:
/**
* @param {Node|null} root
* @return {number[][]}
*/
var levelOrder = function(root) {
if (root == null) return [];
let res = [];
const dfs = function (node, depth) {
res[depth] = res[depth] || [];
res[depth].push(node.val);
for (let item of node.children) item && dfs(item, depth + 1);
}
dfs(root, 0);
return res;
}
参考资料
https://leetcode.cn/problems/n-ary-tree-level-order-traversal/solution/by-ac_oier-yeye/