107. 二叉树的层序遍历 II
给你二叉树的根节点 root
,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
示例 1:
输入: root = [3,9,20,null,null,15,7]
输出:[[15,7],[9,20],[3]]
示例 2:
输入: root = [1]
输出:[[1]]
示例 3:
输入: root = []
输出:[]
提示:
- 树中节点数目在范围
[0, 2000]
内 - − 1000 ≤ N o d e . v a l ≤ 1000 -1000 \leq Node.val \leq 1000 −1000≤Node.val≤1000
解法一(BFS+队列)
思路分析:
- 使用辅助队列,一层一层遍历二叉树,每次将每层遍历的结果保存到一个列表中
- 因为要求返回从底层到顶层的顺序,可以每次保存到列表时从头开始保存,也可以按从上往下顺序保存后,再反转结果列表
实现代码如下:
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> ans = new LinkedList<>(); // 链表从头结点插入花费时间更低
if (root == null)
return ans; // 边界情况
Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new ArrayList<>(); // 数组型花费更小
for (int i = 0; i < size; ++ i) {
TreeNode node = queue.poll();
level.add(node.val);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
ans.add(0, level); // 每次插入每层结点 从头插入
}
return ans;
}
}
提交结果如下:
解答成功:
执行耗时:1 ms,击败了92.83% 的Java用户
内存消耗:41.9 MB,击败了5.03% 的Java用户
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n),只考虑对二叉树结点的遍历
- 空间复杂度: O ( n ) O(n) O(n)
解法二(递归)
思路分析:
- 思路参考LC102.二叉树的层序遍历,在此基础上 需要对最后的结果进行反转
实现代码如下:
class Solution {
// 递归
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> ans = new LinkedList<>(); // 链表从头结点插入花费时间更低
BFS(root, 0, ans);
Collections.reverse(ans);
return ans;
}
private void BFS(TreeNode node, int deeply, List<List<Integer>> ans) {
if (node == null)
return ;
if (deeply >= ans.size()) {
List<Integer> level = new ArrayList<>();
level.add(node.val);
ans.add(level);
} else {
ans.get(deeply).add(node.val);
}
BFS(node.left, deeply + 1, ans);
BFS(node.right, deeply + 1, ans);
}
}
提交结果如下:
解答成功:
执行耗时:1 ms,击败了92.83% 的Java用户
内存消耗:41.4 MB,击败了11.17% 的Java用户
复杂度分析:
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)