本文是记录做该类题的一些思想,效率不算特别高,只是提供一些新的想法;
在LeetCode的剑指offer篇章中,有三个特别近似的打印二叉树的题目,分别是:
(1)剑指Offer 32 - I 从上到下打印二叉树
(2)剑指 Offer 32 - II 从上到下打印二叉树 II
(3)剑指 Offer 32 - III 从上到下打印二叉树 III
三道其实都是BFS;
第一道可以通过创建一个队列实现,利用队列的FIFO实现,将结点从队列取出后,如果子节点非空,就将其子节点放入队列尾部,反复如此,就可以实现这样的效果;
而 || 和 |||可以利用两个队列实现,两个实现的代码几乎一样;
个人做题的思路如下:
(1)创建队列A与队列B,A与B存储相邻不同层的结点;
(2)将A中的结点node依次拿出,之后若node的子节点非空时,将子节点存入队列B中,直到将A为空;
(3)接着队列B进行类似同样的操作,将其中结点的子节点存入A队列中;
(4)最后两个队列为空时即终止;
因为左结点永远会比右子节点先进,所以遍历的顺序是从左到右的;
所以从上到下打印二叉树 II:
/**
* 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) {
Queue<TreeNode> node1 = new LinkedList();
Queue<TreeNode> node2 = new LinkedList();
List<List<Integer>> listAll = new ArrayList<>();
if(root == null){return listAll;}
node1.add(root);
while(!node1.isEmpty()||!node2.isEmpty()){
List<Integer> num = new ArrayList();
while(!node1.isEmpty()){
//取出结点
TreeNode temp = node1.poll();
num.add(temp.val);
//子节点非空时,插入队列node2中
if(temp.left != null) node2.offer(temp.left);
if(temp.right != null) node2.offer(temp.right);
}
if(!num.isEmpty()) listAll.add(new ArrayList(num));
num.clear();
while(!node2.isEmpty()){
//取出结点
TreeNode temp = node2.poll();
num.add(temp.val);
//子节点非空时,插入队列node1中
if(temp.left != null) node1.offer(temp.left);
if(temp.right != null) node1.offer(temp.right);
}
if(!num.isEmpty())listAll.add(new ArrayList(num));
num.clear();
}
return listAll;
}
}
而最后一个在偶数层从右向左输出,则可以通过将list反转即可,而我利用的是以下语句对list反转;
Collections.reverse(num);
还是想说,效率可能不是特别高,但有一个新的点子总会好些,比如刚开始做链表的时候,由1个指针到2个指针,再到3指针,感觉思路一下子就开阔了许多;