题目连接

示例

给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7],

  1. 3<br /> / \<br /> 9 20<br /> / \<br /> 15 7<br />返回锯齿形层序遍历如下:

[
[3],
[20,9],
[15,7]
]

解题思路

沿用第 102 题leectode102-二叉树的层序遍历的思想,修改广度优先搜索,对树进行逐层遍历,用队列维护当前层的所有元素,当队列不为空的时候,求得当前队列的长度 size,每次从队列中取出 size 个元素进行拓展,然后进行下一次迭代。

为了满足题目要求的返回值为「先从左往右,再从右往左」交替输出的锯齿形,我们可以利用「双端队列」的数据结构来维护当前层节点值输出的顺序。双端队列是一个可以在队列任意一端插入元素的队列。

原先逐层遍历的思路不变,维护一个变量 isOrderLeft记录是从左至右还是从右至左的。

  • 如果从左至右,我们每次将被遍历到的元素插入至双端队列的末尾
  • 如果从右至左,我们每次将被遍历到的元素插入至双端队列的头部

当遍历结束的时候我们就得到了答案数组。

代码

  1. // 二叉树的锯齿形层序遍历
  2. public class leetcode103 {
  3. public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
  4. List<List<Integer>> lists = new ArrayList<>();
  5. if (root == null) return lists;
  6. Queue<TreeNode> queue = new LinkedList<>();
  7. queue.offer(root);
  8. boolean isOrderLeft = true;
  9. while (queue.size() > 0){
  10. Deque<Integer> deque = new LinkedList<>();
  11. int size = queue.size();
  12. for (int i=0;i<size;i++){
  13. TreeNode node = queue.poll();
  14. if (isOrderLeft){
  15. deque.offerLast(node.val);
  16. }else {
  17. deque.offerFirst(node.val);
  18. }
  19. if (node.left != null) queue.offer(node.left);
  20. if (node.right != null) queue.offer(node.right);
  21. }
  22. lists.add(new LinkedList<Integer>(deque));
  23. isOrderLeft = !isOrderLeft;
  24. }
  25. return lists;
  26. }
  27. }