题目链接
牛客在线oj题——按之字形顺序打印二叉树
题目描述
给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)
数据范围:0≤n≤1500,
树上每个节点的val满足 ∣val∣<=1500
要求:空间复杂度:O(n),时间复杂度:O(n)
例如:
给定的二叉树是{1,2,3,#,#,4,5}
该二叉树之字形层序遍历的结果是
[
[1],
[3,2],
[4,5]
]
题目示例
示例1
输入:
{1,2,3,#,#,4,5}
返回值:
[[1],[3,2],[4,5]]
说明:
如题面解释,第一层是根节点,从左到右打印结果,第二层从右到左,第三层从左到右。
示例2
输入:
{8,6,10,5,7,9,11}
返回值:
[[8],[10,6],[5,7,9,11]]
示例3
输入:
{1,2,3,4,5}
返回值:
[[1],[3,2],[4,5]]
思路一
定义一个栈stack和一个队列queue,boolean类型变量isRightToLeft = true,将根节点入栈
每次循环前创建ArrayList的list变量,用来存储每一层遍历的元素。确定当前栈的元素个数size(就是当前层所有元素的个数)。
从栈中取出元素,将该元素的值添加进list中,如果当前是需要从右到左遍历,那么先向queue存入当前节点的左子树,再存入右子树。否则先存入当前节点的右子树,再存入左子树(因为栈是先入后出,所以left应该被后遍历时应该被先压入栈)
每一层遍历后对isRightToLeft取反,然后向result中添加list中的元素,再向stack中插入queue中所有元素
而之所以需要定义queue,而不能直接将元素入栈,是因为由于栈是后入先出的,所以添加元素后会影响栈的弹出顺序,所以要等到一层都遍历完后再插入栈
思路一代码
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if(pRoot == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
Stack<TreeNode> stack = new Stack<>();
boolean isRightToLeft = true;
stack.push(pRoot);
while(!stack.isEmpty()){
ArrayList<Integer> list = new ArrayList<>();
int size = stack.size();
while(size != 0){
TreeNode cur = stack.pop();
list.add(cur.val);
TreeNode first = isRightToLeft ? cur.left : cur.right;
TreeNode second = isRightToLeft ? cur.right : cur.left;
if(first != null){
queue.add(first);
}
if(second != null){
queue.add(second);
}
size--;
}
isRightToLeft = !isRightToLeft;
result.add(new ArrayList<>(list));
while(!queue.isEmpty()){
stack.add(queue.poll());
}
}
return result;
}
}
思路二
定义一个boolean类型的变量isLeftToRight,如果为true代表从左向右遍历
按照层序遍历的方法从上到下遍历二叉树,将每一层的节点存储在list中,如果isLeftToRight为false,那么就翻转list
最后将每一层的list存储在result中,直接返回即可
具体层序遍历的思路为:
定义一个队列queue,首先将根节点root进入队列,每次循环都先确定队列中元素个数size,每次弹出size个元素,这一次循环就是代表访问二叉树的一层的元素,然后再将这一层的元素的左子树和右子树(如果存在)分别加入到队列中即可
思路二代码
import java.util.*;
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
ArrayList<ArrayList<Integer>> result = new ArrayList<>();
if(pRoot == null){
return result;
}
Queue<TreeNode> queue = new LinkedList<>();
boolean isLeftToRight = true;
queue.add(pRoot);
while(!queue.isEmpty()){
int size = queue.size();
ArrayList<Integer> list = new ArrayList<>();
while(size != 0){
TreeNode cur = queue.poll();
list.add(cur.val);
if(cur.left != null){
queue.add(cur.left);
}
if(cur.right != null){
queue.add(cur.right);
}
size--;
}
if(!isLeftToRight){
Collections.reverse(list);
}
isLeftToRight = !isLeftToRight;
result.add(new ArrayList<>(list));
}
return result;
}
}