剑指 Offer 32 - III. 从上到下打印二叉树 III
请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。
例如:
给定二叉树: [3,9,20,null,null,15,7]
,
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[20,9],
[15,7]
]
【解析】这次又是在剑指 Offer 32 - II. 从上到下打印二叉树 II的基础上稍作改动,基本思路请点击前面的链接跳转。
这次是在剑指 Offer 32 - II. 从上到下打印二叉树 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) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){return res;}
Queue<TreeNode> que = new LinkedList<TreeNode>();
que.offer(root);
int flag = 1;
while(!que.isEmpty()){
int size = que.size();
LinkedList<Integer> arr = new LinkedList<Integer>();
for(int i=0;i<size;i++){
TreeNode now = que.poll();
if(flag % 2 ==1){arr.addLast(now.val);}
else{arr.addFirst(now.val);}
if(now.left != null){que.offer(now.left);}
if(now.right != null){que.offer(now.right);}
}
res.add(arr);
flag++;
}
return res;
}
}
可以看到,多了一个初始值flag用来判断这层的打印顺序是正是反。在进入每一层开始遍历的时候,首先判断flag的值是奇数还是偶数,奇数则尾插
,偶数则头插
,并且在遍历完一层后将flag 的值+1
即可;
要点总结:
主要还是需要积累一些集合常用的方法。
LinkedList常用方法:
boolean add(E e)
:在链表后增加一个元素
E remove()
:移除链表中第一个元素
E get(int index)
:根据索引取元素
void addFirst(E e)
:头插
void addLast(E e)
:尾插
void add(int index,E e)
:指定位置添加
E removeFirst( )
:删除第一个元素
E removeLast( )
:删除最后一个元素
boolean remove(E e)
:移除指定元素
E remove(int index)
:移除指定位置的元素
E getFirst( )
:获取第一个元素
E getLast( )
:获取最后一个元素