zoukankan      html  css  js  c++  java
  • 二叉树层次遍历

    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

     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     }
    View Code

    解3:引入哨兵结点dummy = null,将每一层分割:  A

                              B    C        Queue: A#BC#  

                      队列中依次poll时, 遇到null,说明这一层结束了。

     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   }
    View Code

    解4: 限定深度的DFS

     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 }
    View Code

     解2:用两个queue:

    // swap q1 and q2
                ArrayList<TreeNode> temp = Q1;
                Q1 = Q2;
                Q2 = temp;

     这样在while循环判断时,只需要判断q1非空即可,循环内部,q2始终放q1结点的子结点,简化代码。

      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;
      }
    View Code
  • 相关阅读:
    BZOJ1854: [Scoi2010]游戏
    NOIP2017 【游记】
    NOIP2017 考前汇总
    最长上升子序列nlogn算法
    BZOJ3110 K大数查询 【线段树 + 整体二分 或 树套树(非正解)】
    BZOJ1089 [SCOI2003]严格n元树 【dp + 高精】
    BZOJ1072 排列perm 【状压dp】
    NOIP2003 传染病控制 【搜索 + 卡时】
    BZOJ 1070 修车 【费用流】
    [SCOI2005]最大子矩阵
  • 原文地址:https://www.cnblogs.com/ddcckkk/p/6828415.html
Copyright © 2011-2022 走看看