LeetCode二叉树专题 (5) 二叉树的层次遍历 II
2020-07-12 本文已影响0人
ZSACH
题目
给定一个二叉树,返回其节点值自底向上的层次遍历。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)题目地址
解题思路
这道题是典型的层序遍历问题。可以先参考LeetCode每日一题 之 二叉树的行数打印
如果使用迭代,只要通过队列先进先出的结构即可。只是不同的是它要求每一层单独的输出,而不是把所有的节点放入一个数组里。这就要求我们判断是否进入了下一个层级,并输出到不同的数组中,怎么判断进入了下一个层级呢。可以先想一想🤔️
有很多种方法可以判断进入了下一个层级,比如我们可以记录每一层的数量,一次遍历只遍历这些数量的节点,或者我们给每个通过null作为分界点,判断是否到了下一层。
如果使用递归的方法呢,我们需要怎么做,可以先想一想🤔️
递归方式
这里我们通过记录每一层的数量,只遍历这些数量的节点,就完成了层级的判断。
public List<List<Integer>> levelOrderBottom(TreeNode root) {
LinkedList<List<Integer>> result = new LinkedList<>();
if (root == null){
return result;
}
//使用队列
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
List<Integer> oneLevel = new ArrayList<>();
// 记录每一层的数量
int count = queue.size();
for (int i = 0; i < count; i++) {
//把下一层所有的节点都遍历完成
TreeNode node = queue.poll();
oneLevel.add(node.val);
if (node.left != null){
queue.add(node.left);
}
if (node.right != null){
queue.add(node.right);
}
}
//因为要求从树的底层开始遍历,所以往前面插入
result.addFirst(oneLevel);
}
return result;
}
递归方式
怎么通过递归的方式完成层序遍历呢,传统的递归,我们都是深度优先的,显然和广度优先的层序遍历要求不符,但是我们是否可以在迭代的时候,记录每一层的层数,这样知道了每一层的层数,我们就可以插入到对应的数组中去了。
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> lists = new ArrayList<>();
func(lists, 0, root);
for (int i = 0, j = lists.size() - 1; i < j; i++, j--) {
List<Integer> temp = lists.get(i);
lists.set(i, lists.get(j));
lists.set(j, temp);
}
return lists;
}
private void func(List<List<Integer>> lists, int level, TreeNode root) {
if (root == null) {
return;
}
//根据层数,找到集合中的对应的数组插入
if (lists.size() == level) {
List<Integer> list = new ArrayList<>();
list.add(root.val);
lists.add(list);
} else {
lists.get(level).add(root.val);
}
func(lists, level + 1, root.left);
func(lists, level + 1, root.right);
}