题目描述
给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回锯齿形层序遍历如下:
[
[3],
[20,9],
[15,7]
]
求解思路
在上一道题(102. 二叉树的层序遍历)的基础上,先试了下用队列是怎么样的。发现这道题应该是不管是哪一层,都是先进后出刚好满足遍历顺序,唯一不同的是正序时先访问左子树再访问右子树,倒序时先访问右子树再访问左子树。于是选择用栈来实现,用变量flag标识式正序访问还是倒序访问。
但还是出现了问题,使用栈结构时,边访问边push进去下一层的节点会影响节点访问顺序。
于是在对每一层遍历时,先用一个List保存一下当前栈中的数据。
代码
执行用时:2 ms, 在所有 Java 提交中击败了17.67%的用户
内存消耗:38.4 MB, 在所有 Java 提交中击败了89.66%的用户
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> re = new ArrayList<>();
Stack<TreeNode> stack = new Stack<TreeNode>(); //栈
if(root==null){
return result;
}
re.add(root.val);
result.add(re);
stack.push(root);
int flag = 1; //1:倒序 0:逆序 标识符
while(!stack.empty()){ //每个循环是访问一层
List<TreeNode> stack1 = new ArrayList<>();
while(!stack.empty()){ //用stack1保存当前栈中的数据,同时出栈
stack1.add(stack.pop());
}
List<Integer> re1 = new ArrayList<>(); //re1存储下一层的所有节点的值
if(flag==1){ //倒序,先右后左
for(int i=0;i<stack1.size();i++){ //直接访问stack1中的数据
TreeNode tr = stack1.get(i);
if(tr.right!=null){
re1.add(tr.right.val);
stack.push(tr.right); //入栈
}
if(tr.left!=null){
re1.add(tr.left.val);
stack.push(tr.left); //入栈
}
}
flag = 0;
}
else{ //正序,先左后右
for(int i=0;i<stack1.size();i++){ //直接访问stack1中的数据
TreeNode tr = stack1.get(i);
if(tr.left!=null){
re1.add(tr.left.val);
stack.push(tr.left); //入栈
}
if(tr.right!=null){
re1.add(tr.right.val);
stack.push(tr.right); //入栈
}
}
flag = 1;
}
if(re1.size()>0){
result.add(re1);
}
}
return result;
}
}