描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
例如:给定的二叉树是{1,2,3,#,#,4,5},该二叉树多行打印层序遍历的结果是
[[1],[2,3],[4,5]]
/* TreeNode类的代码
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
示例
input1:
{8,6,10,5,7,9,11}
output1:
[[8],[6,10],[5,7,9,11]]
input2:
{1,2,3,4,5}
output2:
[[1],[2,3],[4,5]]
思路
根据题目的要求,需要对二叉树进行层序遍历,然而重点是需要将每层的结果单独保存为一个ArrayList
。考虑到这一点,可以使用递归和非递归的方法来完成。
1、非递归:队列
考虑到需要保存每层的结果,因此队列的每一次遍历开始时,队列中只保存二叉树某一层的元素:如第一层只有根结点,第二层只有其左右子树根结点,以此类推。在本方法中,遍历前需要使用queue.size()
来统计队列中当前层的元素个数,同时在执行poll
时需要加入该节点的左右节点(下一层)
时间复杂度:O(N)
。N
为数的结点个数,加入根结点计算1次,循环中对每一个结点都执行了4次运算,O(4N+1)=O(N)
空间复杂度:O(N)
。借助的外部空间有ArrayList、Queue
。其中ArrayList
需要占用N
个结点的空间、Queue
则需要占用O(logN)
个结点的空间,因此共O(N)
import java.util.*;
public class Solution {
ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
if(pRoot == null) return list;
TreeNode tmp = null;
int size = 0, i = 0;
Queue<TreeNode> que = new LinkedList<>();
ArrayList<Integer> arr = null;
que.offer(pRoot);
while(!que.isEmpty()){
size = que.size();//获取当前层的结点个数
i = 0;
arr = new ArrayList<>();
while(i++ < size){
tmp = que.poll();
arr.add(tmp.val);
if(tmp.left != null) que.offer(tmp.left);
if(tmp.right != null) que.offer(tmp.right);
}
list.add(arr);
}
return list;
}
}
2、递归实现:记录数的深度
考虑到递归中无法判断当前结点在哪一层,因此需要额外指定一个参数来记录数的层次(即当前层的深度)。
import java.util.ArrayList;
public class Solution {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
void dfs(TreeNode node, int deep){
//给每一层的结点新建一个`ArrayList`来保存
if(list.size() < deep) list.add(new ArrayList<Integer>());
list.get(deep-1).add(node.val);
//由于加了`null`判断,因此遇到叶子结点自动执行结束,无需另加递归出口
if(node.left != null) dfs(node.left, deep+1);
if(node.right != null) dfs(node.right, deep+1);
}
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
//注意:递归没有另加出口,因此这里需要加为空判断
if(pRoot == null) return list;
dfs(pRoot, 1);
return list;
}
}