Given a binary tree, return the zigzag level order traversal of its nodes' values. (ie, from left to right, then right to left for the next level and alternate between). For example: Given binary tree {3,9,20,#,#,15,7}, 3 / 9 20 / 15 7 return its zigzag level order traversal as: [ [3], [20,9], [15,7] ]
参考这道题其实还是树的层序遍历Binary Tree Level Order Traversal。不过这里稍微做了一点变体。在Binary Tree Level Order Traversal中我们是维护了一个队列来完成遍历,而在这里为了使每次都倒序出来,我们很容易想到用栈的结构来完成这个操作。有一个区别是这里我们需要一层一层的来处理(原来可以按队列插入就可以,因为后进来的元素不会先处理),所以会同时维护新旧两个栈,一个来读取,一个存储下一层结点。总体来说还是一次遍历完成,所以时间复杂度是O(n),空间复杂度最坏是两层的结点,所以数量级还是O(n)(满二叉树最后一层的结点是n/2个)。代码如下:
第二遍做法:几个设定: Pstack为父亲节点这一层的node集合,Cstack用来存子节点这一层的node;root节点一层为第0层; 节点在出栈的时候加入List; 偶数层先加左child再加右child进入Child Stack中,这样pop出来的时候是先右child再左child;奇数层先加右child再加左child。需要注意的是15-16行的 != Null 条件很必要,否则栈里面会有null, 这样栈也不为空。循环继续执行,但是null元素到第13行.val就会出错
1 public class Solution { 2 public ArrayList<ArrayList<Integer>> zigzagLevelOrder(TreeNode root) { 3 ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); 4 if (root == null) return res; 5 LinkedList<TreeNode> Pstack = new LinkedList<TreeNode>(); 6 LinkedList<TreeNode> Cstack = new LinkedList<TreeNode>(); 7 Pstack.push(root); 8 int level = 0; 9 while (!Pstack.isEmpty()) { 10 ArrayList<Integer> item = new ArrayList<Integer>(); 11 while (!Pstack.isEmpty()) { 12 root = Pstack.pop(); 13 item.add(root.val); 14 if (level % 2 == 0) { 15 if (root.left != null) Cstack.push(root.left); 16 if (root.right != null) Cstack.push(root.right); 17 } 18 else { 19 if (root.right != null) Cstack.push(root.right); 20 if (root.left != null) Cstack.push(root.left); 21 } 22 } 23 res.add(new ArrayList<Integer>(item)); 24 Pstack = Cstack; 25 Cstack = new LinkedList<TreeNode>(); 26 level++; 27 } 28 return res; 29 }
贴一个DFS做法:很好
- O(n) solution by using LinkedList along with ArrayList. So insertion in the inner list and outer list are both O(1),
- Using DFS and creating new lists when needed.
1 public class Solution { 2 public List<List<Integer>> zigzagLevelOrder(TreeNode root) 3 { 4 List<List<Integer>> sol = new ArrayList<>(); 5 travel(root, sol, 0); 6 return sol; 7 } 8 9 private void travel(TreeNode curr, List<List<Integer>> sol, int level) 10 { 11 if(curr == null) return; 12 13 if(sol.size() <= level) 14 { 15 List<Integer> newLevel = new LinkedList<>(); 16 sol.add(newLevel); 17 } 18 19 List<Integer> collection = sol.get(level); 20 if(level % 2 == 0) collection.add(curr.val); 21 else collection.add(0, curr.val); 22 23 travel(curr.left, sol, level + 1); 24 travel(curr.right, sol, level + 1); 25 } 26 }