N 叉树的层序遍历

126 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

一、题目

leetcode 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广度优先搜索,按照根节点开始,往下层层获取子树,然后按层将每一层的节点依次从左到右添加到结果集中,同时需要一个队列辅助遍历,因为队列先进先出,可以将当前层下的子树依次添加到队列中,然后保证每次只取当前层的节点出来。 具体的首先判断root树不为空才执行遍历操作,新建一个queue队列,首先将root树放入队列中,此时队列里面的元素只有root一个树,然后我们遍历第一层的元素(只有root根节点的),然后需要循环遍历queue队列的元素(因为循环中还会往队列添加子树的)。 首先记录下当前层有多少个元素size,代表当前层的元素节点数量,因为每一次循环之后的队列中的元素都是子树。然后我们需要再将queue队列头部的前size个元素取出。然后记录下取出的子树根节点值到结果集,同时再将其子树追加到队列尾部。当取出了size个元素后 代表获取完了当前层的节点值了,记录下之后就可以继续下一层直到队列没有元素。

方法二 同时也可以使用DFS深度优先搜索,我们从root树的根节点开始,递归遍历其子树节点,同时需要记录一个层号来表示当前层的元素。具体的定义dfs递归函数,参数需要一个node遍历的树,一个rootLever代表层号。因为返回的结果集是数组的形式,所以 我们可以利用数组的下标来与示层号对应,数组0代表第一层元素节点就是root树根节点。首先递归判断当前node树为空则结束,然后如果是第一次到达该层,我们需要新建一个list数组,否则直接到结果集中取出当前rootLever层的list数组,然后将当前树的节点值 添加到list数组和结果集中,然后再去递归当前树下一层的节点,注意rootLever需要加1递归下去,最终返回结果即可。

三、代码

方法一 Java代码

class Solution {
    public List<List<Integer>> levelOrder(Node root) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        if (root == null) {
            return result;
        }
        Deque<Node> deque = new ArrayDeque<>();
        deque.add(root);
        while (!deque.isEmpty()) {
            int size = deque.size();
            List<Integer> lever = new ArrayList<>();
            while (size-- > 0) {
                Node first = deque.pollFirst();
                if (first == null) {
                    continue;
                }
                lever.add(first.val);
                for (Node node : first.children) {
                    deque.offerLast(node);
                }
            }
            result.add(lever);
        }
        return result;
    }
}

时间复杂度:O(n),需要循环遍历树的每一个节点。

空间复杂度:O(n),需要一个结果集数组以及一个队列辅助。


方法二 Java代码

class Solution {
    List<List<Integer>> result = new ArrayList<List<Integer>>();

    public List<List<Integer>> levelOrder(Node root) {
        dfs(root, 0);
        return result;
    }

    private void dfs(Node node, int rootLever) {
        if (node == null) {
            return;
        }
        List<Integer> lever = result.size() <= rootLever ? new ArrayList<>() : result.get(rootLever);
        lever.add(node.val);
        if (result.size() <= rootLever){
            result.add(lever);
        }
        for (Node child : node.children) {
            dfs(child, rootLever + 1);
        }
    }
}

时间复杂度:O(n),需要递归遍历树的每一个节点。

空间复杂度:O(1),需要一个结果集数组以及栈空间。