107. 二叉树的层次遍历 II (简单)
题目描述
给定一个二叉树, 返回自底向上的层次遍历, 并返回一个二维数组.
比如说,给你的二叉树是:
1
/ \
2 4
/ \
8 16
它的逆层序遍历结果是:
[
[8, 16],
[2, 4],
[1],
]
本题和第102题-二叉树的层次遍历类似, 只不过遍历顺序不同.
题目解析
解法一: DFS
把 102 题 的DFS贴过来看一下。
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
DFS(root, 0, ans);
return ans;
}
private void DFS(TreeNode root, int level, List<List<Integer>> ans) {
if(root == null){
return;
}
//当前层数还没有元素,先 new 一个空的列表
if(ans.size()<=level){
ans.add(new ArrayList<>());
}
//当前值加入
ans.get(level).add(root.val);
DFS(root.left,level+1,ans);
DFS(root.right,level+1,ans);
}
Copy
之前我们根据 level 得到数组的位置,然后添加。
ans.get(level).add(root.val);
ans [] [] [] [] [].
index 0 1 2 3 4
level 0 1 2 3 4
------------>
index = 0 + level
现在 level 是逆过来存的
ans [] [] [] [] [].
index 0 1 2 3 4
level 4 3 2 1 0
<------------
index = 4 - level
4 就是 ans 的末尾下标,就是 ans.size() - 1
所以代码变为
ans.get(ans.size() - 1 - level).add(root.val);
Copy
此外还有句代码要改。
if(ans.size()<=level){
ans.add(new ArrayList<>());
}
在添加当前 level 的第一个元素的时候,首先添加一个空列表到 ans 中
假设当前 level = 2,ans 中只添加了 level 是 0 和 1 的元素
ans [3] [9]
index 0 1
level 1 0
因为 level 是从右往左增加的,所以空列表要到 ans 的头部
ans [] [3] [9]
index 0 1 2
level 2 1 0
所以代码改成下边的样子
ans.add(0,new ArrayList<>());
Copy
综上,只要改了这两处就可以了。
// DFS方式
public void DFS(TreeNode root, List<List<Integer>> ans, int level) {
if (root == null) {
return;
}
if (ans.size() <= level) {
// 这部分需要将空数组存到数组的头部, 因为是反着存的
ans.add(0, new ArrayList<>());
}
// 关键部分, 使用下标来反着存
ans.get(ans.size()-1-level).add(root.val);
DFS(root.left, ans, level + 1);
DFS(root.right, ans, level + 1);
}
public List<List<Integer>> levelOrderRecursive(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if (root == null) {
return ans;
}
DFS(root, ans, 0);
return ans;
}
解法二: BFS
相比于正常的遍历, 只需要改一行代码即可.
// BFS方式(队列)
public List<List<Integer>> levelOrderIterative(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if (root == null) {
return ans;
}
queue.offer(root);
int cnt = 0;
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> subList = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode s = queue.poll();
subList.add(s.val);
if (s.left != null) queue.offer(s.left);
if (s.right != null) queue.offer(s.right);
}
// 这里就是变动的部分, 改为插入到头部即可.
ans.add(0, subList);
}
return ans;
}
综合
本题和第102题-二叉树的层次遍历类似, 只需要在上一题的基础上, 寻找到level和index之间的对应关系即可.
此外, 因为我们在头部添加元素, 所以用链表会好一些, 如果用ArrayList, 插入需要整体后移, 时间会增加一些.

366

被折叠的 条评论
为什么被折叠?



