一、需求
- 给定一个二叉树,返回其节点值自底向上的层序遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历);
例如:
给定二叉树[3,9,20,null,null,15,7]
3 / \ 9 20 / \ 15 7返回其自底向上的层序遍历为:
[ [15,7], [9,20], [3] ]
二、BFS法1
2.1 思路分析
- 根据从上到下打印二叉树II:https://blog.csdn.net/Sruggle/article/details/108064919的思路,这里就是最后对list来一次反转;
2.2 代码实现
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(queue.size() != 0) {
List<Integer> tmp = new ArrayList<>();
int count = queue.size();
while(count != 0) {
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
count--;
}
res.add(tmp);
}
Collections.reverse(res);
return res;
}
}
2.3 复杂度分析
- 时间复杂度为O(N),其中N为二叉树中的元素个数,需要遍历所有的元素;
- 空间复杂度为O(N),队列最多同时存储 N/2 个元素;
三、BFS法2
3.1 思路分析
- 利用LinkedList,每次将二叉树的每一行添加到第一个位置,这就省去了方法2中的反转带来的复杂度;
3.2 代码实现
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
LinkedList<List<Integer>> res = new LinkedList<>();
if(root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(queue.size() != 0) {
List<Integer> tmp = new ArrayList<>();
int count = queue.size();
while(count != 0) {
TreeNode node = queue.poll();
tmp.add(node.val);
if(node.left != null) queue.add(node.left);
if(node.right != null) queue.add(node.right);
count--;
}
res.addFirst(tmp);
}
return res;
}
}