方法1:使用一个队列(用于层次遍历:所有层),加一个栈(用于高效翻转:偶数层)
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
if(pRoot == null)return res;
Stack<Integer> stack = new Stack<Integer>();//stack仅用于偶数层翻转val
ArrayList<TreeNode> queue = new ArrayList<TreeNode>();//queue是奇偶共用
queue.add(pRoot);
int layer = 1;//层数用layer (区别于深度depth = layer-1)
while(!queue.isEmpty()){
ArrayList<Integer> list = new ArrayList<Integer>();//新建行
int size = queue.size();//出本层前记录size,不然难以做到层数的切分 //提前写出来,因为size会变
for(int i=0; i<=size-1; ++i){
TreeNode node = queue.get(0);//一定要新建node副本,不然是引用会变
queue.remove(0);
if(layer % 2 == 1){
list.add(node.val);
}
else{//偶数行,需要栈翻转
stack.push(node.val);
}
if(node.left != null)queue.add(node.left);
if(node.right != null)queue.add(node.right);
}
while(!stack.isEmpty()){
list.add(stack.pop());//偶数层一次性添加,奇数层一个个添加
}
res.add(list);
++layer;//本层结束,层数加一
}
return res;
}
}//时间、空间复杂度,都是树的规模 O(N) 方法2:使用一个队列(用于层次遍历),加一个ArrayList(偶行、奇行分别头插、尾插)
import java.util.ArrayList;
public class Solution {//方法2和方法1相比,代码区别仅仅是把stack相关删去,然后换成ArrayList头插法
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
if(pRoot == null)return res;
ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
queue.add(pRoot);
int layer = 1;
while(!queue.isEmpty()){
ArrayList<Integer> list = new ArrayList<Integer>();
int size = queue.size();
for(int i=0; i<=size-1; ++i){
TreeNode node = queue.get(0);
queue.remove(0);
if(layer % 2 == 1){
list.add(node.val);
}
else{
list.add(0,node.val);//头插法,逆序 //【代码简洁,但效率比Stack低】
}
if(node.left != null)queue.add(node.left);
if(node.right != null)queue.add(node.right);
}
res.add(list);
++layer;
}
return res;
}
}//时间、空间都是 O(N) 
京公网安备 11010502036488号