给定一个节点数为 n 二叉树,要求从上到下按层打印二叉树的 val 值,同一层结点从左至右输出,每一层输出一行,将输出的结果存放到一个二维数组中返回。
例如:
给定的二叉树是{1,2,3,#,#,4,5}
该二叉树多行打印层序遍历的结果是
[
[1],
[2,3],
[4,5]
]
思路:
题目要求将二叉树按行打印,即按层打印,其中每层分开。不难想到,要使用层次遍历,但是难点在于如何每层分开存储,从哪里知晓分开的时机?在层次遍历的时候,我们通常会借助队列(queue),事实上,队列中的值大有玄机,让我们一起来看看:
- 当根节点进入队列时,队列长度为1,第一层节点数也为1
- 若是根节点有两个子节点,push进队列后,队列长度为2,第二层节点数也为2;若是根节点一个子节点,push进队列后,队列长度为为1,第二层节点数也为1.
- 由此,我们可知,每层的节点数等于进入该层时队列长度,因为刚进入该层时,这一层每个节点都会push进队列,而上一层的节点都出去了。
- 综上,反过来,每次只要在队列长度内循环,必定是一层,一层访问完毕再更新队列长度即可。
代码如下:
ArrayList<ArrayList<Integer> > Print(TreeNode root) {
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
if(root == null)
return res;
//队列存储,进行层次遍历
Queue<TreeNode> q = new LinkedList<>();
q.offer(root);
while(!q.isEmpty()){
//记录二叉树的某一行
ArrayList<Integer> list = new ArrayList<>();
int n = q.size();
//因先进入的是根节点,故每层节点多少,队列大小就是多少
for(int i = 0;i < n;i++){
TreeNode cur = q.poll();
list.add(cur.val);
//若是左右孩子存在,则存入左右孩子作为下一个层次
if(cur.left != null)
q.offer(cur.left);
if(cur.right != null)
q.offer(cur.right);
}
res.add(list);
}
return res;
}