给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7]
,
3 / \ 9 20 / \ 15 7
返回锯齿形层次遍历如下:
[ [3], [20,9], [15,7] ]
题意要求实现每遍历一层就反序一次,可以用两个栈,遍历第i层时将这一层的所有子节点放入另一个栈中,遍历结束后再遍历另一个栈,另一个栈的所有子节点再放入这个栈中,不断循环,直至所有的节点都被访问过为止。
注意两次循环进栈的顺序是不一样的。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root==null)return res;
Stack<TreeNode> s1 = new Stack<>();
Stack<TreeNode> s2 = new Stack<>();
s1.push(root);
List<Integer> tmp = new ArrayList<>();
while(!s1.empty()){
while(!s1.empty()){
TreeNode r = s1.pop();
tmp.add(r.val);
if(r.left!=null){
s2.push(r.left);
}
if(r.right!=null){
s2.push(r.right);
}
if(s1.empty()){
res.add(tmp);
tmp = new ArrayList<>();
}
}
while(!s2.empty()){
TreeNode r = s2.pop();
tmp.add(r.val);
if(r.right!=null){
s1.push(r.right);
}
if(r.left!=null){
s1.push(r.left);
}
if(s2.empty()){
res.add(tmp);
tmp = new ArrayList<>();
}
}
}
return res;
}
}
还有一种递归的解法,当处于第i层时,根据i的奇偶性来判断这一层是应该从左到右还是从右到左遍历,若是从左到右就向这一层对应的list中add该节点的值,否则就将该节点的值添加到list的左端,以此实现反序。当层数大于res的大小时,应该为res添加一个新的ArrayList,表示新的一层。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
dfs(res,1,root);
return res;
}
public void dfs(List<List<Integer>> res,int level,TreeNode root){
if(root==null)return ;
if(level>res.size()){
//到达下一层
res.add(new ArrayList<Integer>());
}
if(level%2==1){
res.get(level-1).add(root.val);
}
else{
res.get(level-1).add(0,root.val);
}
dfs(res,level+1,root.left);
dfs(res,level+1,root.right);
}
}