从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
思路 层序遍历 队列
每次打印一个节点的时候,如果该节点有子节点,则把该节点的子节点放到队列的末尾,到队列的头部取出最早进入队列的节点,
用到的数据结构
- ArrayList<ArrayList> result = new ArrayList<ArrayList>();
用 ArrayList<ArrayList> 存最终结果,多对数组 - Queue queue = new LinkedList();
用队列 和链表来模拟层序遍历得到按顺序的元素 - ArrayList layerList = new ArrayList();
用 ArrayList 存每层的元素
5.13总结
这样写很便捷
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root==null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
while(!queue.isEmpty()){
int count = queue.size();
List<Integer> list = new ArrayList<>();
while(count>0){
TreeNode node = queue.poll();
list.add(node.val);
if(node.left!=null)
queue.add(node.left);
if(node.right!=null)
queue.add(node.right);
count--;
}
res.add(list);
}
return res;
}
}
层序遍历
层序遍历的模板是用一个队列,入队每次遇到的非空结点,出队当前最前结点,直到队列为空,遍历完成
现在为了保存层数信息,我们添加了map,每次入队新的结点,map 保存 <结点,层数> 的 <K,V> 对
关于相同层数如何入 lists,前面也讨论这就不赘述了
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.*;
public class Solution {
ArrayList<ArrayList<Integer> > Print(TreeNode root) {
ArrayList<ArrayList<Integer>> lists = new ArrayList<>();
if(root==null)
return lists;
HashMap<TreeNode, Integer> map = new HashMap<>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
//queue是抽象的不能被实例化,用LinkedList
queue.add(root);
map.put(root, 0);
while (!queue.isEmpty()) {
root = queue.poll();
int deep = map.get(root);
if (root.left != null) {
queue.add(root.left);
map.put(root.left, deep + 1);
}
if (root.right != null) {
queue.add(root.right);
map.put(root.right, deep + 1);
}
if (lists.size() <= deep) {
ArrayList<Integer> list = new ArrayList<>();
list.add(root.val);
lists.add(list);
} else {
ArrayList<Integer> list = lists.get(deep);
list.add(root.val);
}
}
return lists;
}
}
时间复杂度:O(n)O(n)
空间复杂度:O(n)O(n)
递归
好好思考
其实我们层序遍历一般不会用递归实现,但是这道题比较特殊,特殊之处在于,保存层数的 deep 可以索引出对应的层信息,方便结点直接找到同一层其他结点
我们考虑的问题就变成如何让同一层结点从左到右依次打印,第一个要点肯定是保证入队的顺序,先左子树,后右子树,再一个要点是需要保证建立 list 的顺序,即上一层的 list 先建立先存储进 lists,综合考虑,选用前序遍历的模板
关于相同层数如何入 lists,前面也讨论这就不赘述了
//用递归做的
public class Solution {
ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> list = new ArrayList<>();
depth(pRoot, 0, list);
return list;
}
private void depth(TreeNode root, int depth, ArrayList<ArrayList<Integer>> list) {
if(root == null) return;
if(depth > =list.size())
list.add(new ArrayList<Integer>());
list.get(depth).add(root.val);
depth(root.left, depth + 1, list);
depth(root.right, depth + 1, list);
}
}