题目描述
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。


刚开始想法是用的print,然后看到题目给的是ArrayList<ArrayList<Integer> >还有点小懵逼。其实是让你返回一个ArrayList,其中每个元素都是一个装了整型数据的ArrayList。比如{[8],[9,10],[11,12,13]}这样的返回方式。比如树有3层,大括号表示的ArrayList就应该装了3个元素。中括号的ArrayList就表示这颗树某一层的所有节点。用这样的方式来区别换行。
另外做本题之前。最好先知道普通版怎么写(不换行打印)。然后在之前的版本上迭代就行。里面有几个点需要注意。在普通版本中,存放元素的ArrayList对象new一个就够了,但本题在返回类型是ArrayList<ArrayList<Integer> >时,不能只new一个,之前分析的有[8],[9,10],[11,12,13]这样的3个ArrayList,因此每while一次(每遍历一层),都需要重新new一个ArrayList存放当前层的所有节点。

import java.util.LinkedList;
import java.util.Queue;
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> arrplus = new ArrayList<ArrayList<Integer>>();
        if(pRoot==null)
            return arrplus; //这里最好返回arrplus而不是null
        Queue<TreeNode> queue = new LinkedList<TreeNode>();      
        queue.offer(pRoot);
        while(!queue.isEmpty()){  
            //这里的arr一定在while里边每次新建一个,因为arr不是复用的。有多个arr
            ArrayList<Integer> arr = new ArrayList<Integer>();
            //这里也要注意,queue的size随时变动,因此进入for循环前拿到这个变量。
            int size = queue.size();        
            for(int i=0;i<size;i++){
                TreeNode temp = queue.poll();
                arr.add(temp.val);
                if(temp.left!=null)
                    queue.offer(temp.left);
                if(temp.right!=null)
                    queue.offer(temp.right);
            }
            arrplus.add(arr);
        }
        return arrplus;
    } 
}

并不是新解法,而是锻炼自己的基本功,将if改成while。

import java.util.LinkedList;
import java.util.Queue;
public class Solution {
    ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> arrplus = new ArrayList<ArrayList<Integer>>();
        if(pRoot==null)
            return arrplus; //这里最好返回arrplus而不是null
        Queue<TreeNode> queue = new LinkedList<TreeNode>();      
        queue.offer(pRoot);
        while(!queue.isEmpty()){  
            //这里的arr一定在外层的while里边每次新建一个,因为arr不是复用的。有多个arr
            ArrayList<Integer> arr = new ArrayList<Integer>();
            //这里也要注意,queue的size随时变动,因此进入里层while循环前拿到这个变量。
            int size = queue.size();        
            while(size>0){//或者再用一个变量count,赋值为0,每次循环++,相等时结束当前循环
                TreeNode temp = queue.poll();
                arr.add(temp.val);
                if(temp.left!=null)
                    queue.offer(temp.left);
                if(temp.right!=null)
                    queue.offer(temp.right);
               size--;
            }
            arrplus.add(arr);
        }
        return arrplus;
    } 
}

而如果是打印版本,使用print时,区别在于,arr数组变成了一个变量count,用来记录当前层遍历了几个,而size保持不变,依旧是当前层的所有节点,当遍历完后,进入下一轮循环时,输出一个换行符。而里层的循环条件则变成了count == size。只有当前层遍历所有节点时,结束这一层的循环,并在结束前更新size(或者在下一轮循环开始前更新size)。