103. Binary Tree Zigzag Level Order Traversal
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,null,null,15,7], 3 / \ 9 20 / \ 15 7 return its zigzag level order traversal as: [ [3], [20,9], [15,7] ]
在Binary Tree Level Order Traversal中我们是维护了一个队列来完成遍历,而在这里为了使每次都倒序出来,我们很容易想到用栈的结构来完成这个操作。有一个区别是这里我们需要一层一层的来处理(原来可以按队列插入就可以,因为后进来的元素不会先处理),所以会同时维护新旧两个栈,一个来读取,一个存储下一层结点。总体来说还是一次遍历完成,所以时间复杂度是O(n),空间复杂度最坏是两层的结点,所以数量级还是O(n)(满二叉树最后一层的结点是n/2个)。
public class Solution { public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> res = new ArrayList<>(); if(root == null) return res; Queue<TreeNode> q = new LinkedList<>(); q.add(root); boolean order = true; int size = 1; while(!q.isEmpty()) { List<Integer> tmp = new ArrayList<>(); for(int i = 0; i < size; ++i) { TreeNode n = q.poll(); if(order) { tmp.add(n.val); } else { tmp.add(0, n.val); } if(n.left != null) q.add(n.left); if(n.right != null) q.add(n.right); } res.add(tmp); size = q.size(); order = order ? false : true; } return res; } }
Queue is not helpful here one must consider using Stack instead.
This problem can be solved using two stacks (one called currentLevel and the other one called nextLevel). Also need a variable to keep track of the current level’s order
(whether it is left------>right or right-.------->left).
You pop from stack currentLevel and store it in a vector . Whenever the current level’s order is from left->right, push the node’s left child, then its right child to stack nextLevel.
NOTE: Stack is a Last In First OUT (LIFO) structure, so the next time when nodes are popped off nextLevel, it will be in the reverseorder.
On the other hand, when the current level’s order is from right->left, you would push the node’s right child first, then its left child. Swap those two stacks at the end of each level (ie, when currentLevel is empty).
O(n) time complexity as every node is visited only once O(n) Space complexity for extra stack space.
public ArrayList<ArrayList<Integer>> zigzagLevelOrder(TreeNode root) { ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); if(root==null) return res; LinkedList<TreeNode> stack = new LinkedList<TreeNode>(); int level=1; ArrayList<Integer> item = new ArrayList<Integer>(); item.add(root.val); res.add(item); stack.push(root); while(!stack.isEmpty()) { LinkedList<TreeNode> newStack = new LinkedList<TreeNode>(); item = new ArrayList<Integer>(); while(!stack.isEmpty()) { TreeNode node = stack.pop(); if(level%2==0) { if(node.left!=null) { newStack.push(node.left); item.add(node.left.val); } if(node.right!=null) { newStack.push(node.right); item.add(node.right.val); } } else { if(node.right!=null) { newStack.push(node.right); item.add(node.right.val); } if(node.left!=null) { newStack.push(node.left); item.add(node.left.val); } } } level++; if(item.size()>0) res.add(item); stack = newStack; } return res; }
层次遍历+ 逆序偶数行
贴一个DFS做法:很好, 但是还是bfs 好想, 以后再研究
- 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.
public class Solution { public List<List<Integer>> zigzagLevelOrder(TreeNode root) { List<List<Integer>> sol = new ArrayList<>(); travel(root, sol, 0); return sol; } private void travel(TreeNode curr, List<List<Integer>> sol, int level) { if(curr == null) return; if(sol.size() <= level) { List<Integer> newLevel = new LinkedList<>(); sol.add(newLevel); } List<Integer> collection = sol.get(level); if(level % 2 == 0) collection.add(curr.val); else collection.add(0, curr.val); travel(curr.left, sol, level + 1); travel(curr.right, sol, level + 1); } }