思路很简单:我用了三个额外的变量来记录遍历时的状态
levelCount:遍历到了当前层的第几个节点
levelAmout:该层一共有多少个节点
nextLevelAmount:下一层一共有多少个节点

状态更新:
//我的代码是先判断状态后访问本轮节点
如果levelCount==levelAmount则说明上一层已经遍历完了,本轮是新的一层的开始{
重置levelCount为0
更新levelAmount为本层节点数(即nextLevelAmount)
重置nextLevelAmount为0开始下一层计数

每遍历一个节点就levelCount++
每入栈一个节点就nextLevelAmount++

这种解法不需要第二个队列,只需要3个额外的变量,除了多了三个变量的更新和一个判断操作外,代码流程和完全二叉树的层次遍历一模一样

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode类 
     * @return int整型ArrayList<ArrayList<>>
     */
    public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {
        // write code here
        if(root==null)return new ArrayList<ArrayList<Integer>>();
        ArrayList<ArrayList<Integer>>res=new ArrayList<ArrayList<Integer>>();

        //状态变量
        int levelCount=0;
        int levelAmount=1;
        int nextLevelAmount=0;

        //下面的代码除了更新和判断操作,其余流程和完全2叉树的层次遍历一模一样,无需改动
        ArrayDeque<TreeNode>queue=new ArrayDeque ();
        queue.addLast(root);
        TreeNode cur;
        ArrayList<Integer>levelRes=new ArrayList<Integer>();
        while(!queue.isEmpty()){
            //判断:先判断本轮是新的一层的开始还是是上一层的继续
            if(levelCount==levelAmount){
                levelAmount=nextLevelAmount;
                levelCount=0;
                nextLevelAmount=0;
                res.add(levelRes);
                levelRes=new ArrayList<Integer>();
            }

            //访问
            cur=queue.pollFirst();
            levelRes.add(cur.val);
            levelCount++;//更新操作
            if(cur.left!=null){
                queue.addLast(cur.left);
                nextLevelAmount++;//更新操作
            }
            if(cur.right!=null){
                queue.addLast(cur.right);
                nextLevelAmount++;//更新操作
            }
        }
        res.add(levelRes);//别忘了最后一层的结果还没加到结果集
        return res;
    }
}