一起养成写作习惯!这是我参与「掘金日新计划 · 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),需要一个结果集数组以及栈空间。