LeetCode 429. N 叉树的层序遍历

429. N 叉树的层序遍历

描述

给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。

树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。

示例

示例1
示例1

输入:root = [1,null,3,2,4,null,5,6]
输出:[[1],[3,2,4],[5,6]]

示例2
示例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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值