http://www.lintcode.com/zh-cn/problem/binary-tree-level-order-traversal/#
注意点:1.分割层的三种方式: 1.提前记录好每层的结点数目,poll时poll指定数目的结点;
2.用两个Queue,每个queue中只放一层的结点
3.引入哨兵结点作为标记,遇到哨兵结点说明层结束了(相当于层结束符)
2.因为result里存的是level的内存地址,而并不是层序遍历的值,所以对每一层都必须new一个level,而不能clear后重复使用。
3.看解4代码,区分什么是DFS,BFS
错误点:queue是抽象的,实例化时,实例成LinkedList
q.isEmpyt() 不是q.empty()
入队 q.offer(E) 出队 q.poll()
解1:一个queue
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) { 2 ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); 3 if(root == null) return result; 4 Queue<TreeNode> q = new LinkedList<TreeNode>(); 5 q.offer(root); 6 ArrayList<Integer> arr = null; 7 while(!q.isEmpty()){ 8 arr = new ArrayList<Integer>(); 9 int num = q.size(); 10 for(int i = 0; i <num; i++) { 11 TreeNode temp = q.poll(); 12 arr.add(temp.val); 13 if(temp.left != null) q.offer(temp.left); 14 if(temp.right != null) q.offer(temp.right); 15 } 16 result.add(arr); 17 } 18 return result; 19 }
解3:引入哨兵结点dummy = null,将每一层分割: A
B C Queue: A#BC#
队列中依次poll时, 遇到null,说明这一层结束了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) { 2 ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); 3 if (root == null) return result; 4 Queue<TreeNode> q = new LinkedList<TreeNode>(); 5 q.offer(root); 6 q.offer(null); 7 ArrayList<Integer> level = new ArrayList<Integer>(); 8 while(!q.isEmpty()) { 9 TreeNode temp = q.poll(); 10 if(temp != null) { 11 level.add(temp.val); 12 if(temp.left != null) q.offer(temp.left); 13 if(temp.right != null) q.offer(temp.right); 14 // continue; 这里可以写成continue,也可以用else,两种方法都行。 15 } else { 16 q.offer(null); 17 if(level.size() == 0) break; 18 result.add(level); 19 level = new ArrayList<Integer>(); //这里不能level.clear();因为result里存的是level的内存地址,而并不是层序遍历的值,clear后,result里存的都是 20 //空List,所以必须是新建一个List引用,而用原来的lIst是不行的。 21 } 22 } 23 return result; 24 }
解4: 限定深度的DFS
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) { 2 ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); 3 if (root == null) return result; 4 int targetDep = 1, currDep = 1; 5 ArrayList<Integer> level = new ArrayList<Integer>(); 6 while(true) { 7 dfs(root,currDep,targetDep,level); 8 if(level.size() == 0) break; 9 result.add(level); 10 level = new ArrayList<Integer>(); 11 targetDep++; 12 currDep = 1; // 写不写都行,说明dfs在传currDep时是值传递,在调用过程中,值并不会发生变化。 13 } 14 return result; 15 16 } 17 // 函数在调用过程中调用了自己本身,迭代调用,说明是深度优先;BFS是不会有递归的调用的。 18 private void dfs(TreeNode root, int currDep, int targetDep, ArrayList<Integer> level) { 19 if(root == null || currDep > targetDep) return; 20 if(currDep == targetDep) level.add(root.val); 21 dfs(root.left, currDep + 1, targetDep, level); 22 dfs(root.right, currDep + 1, targetDep, level); 23 }
解2:用两个queue:
// swap q1 and q2
ArrayList<TreeNode> temp = Q1;
Q1 = Q2;
Q2 = temp;
这样在while循环判断时,只需要判断q1非空即可,循环内部,q2始终放q1结点的子结点,简化代码。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root) { ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>(); if(root == null) return result; Queue<TreeNode> q1 = new LinkedList<TreeNode>(); Queue<TreeNode> q2 = new LinkedList<TreeNode>(); q1.offer(root); while(!q1.isEmpyt() || !q2.isEmpyt()) { if(!q1.isEmpyt()) { ArrayList<Integer> level = new ArrayList<Integer>(); TreeNode temp = null; while((temp = q1.poll()) != null) { if(temp.left != null) q2.offer(temp.left); if(temp.right != null) q2.offer(temp.right); level.add(temp.val); } } if(!q2.isEmpyt()) { ArrayList<Integer> level = new ArrayList<Integer>(); TreeNode temp = null; while((temp = q2.poll()) != null) { if(temp.left != null) q1.offer(temp.left); if(temp.right != null) q1.offer(temp.right); level.add(temp.val); } } } return result; }