问题描述
给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
行)。
例如:
给定二叉树 [3,9,20,null,null,15,7],
返回锯齿形层次遍历如下:
[
[3],
[20,9],
[15,7]
]
问题解法
首先这是二叉树的问题很容易就想到dfs与bfs。但是分析发现队列只能保证顺序输出,当改变顺序即锯齿输出时,需要知道前一个的左右节点。因此如果保证队列输出就需要将进队的顺序进行改变。又因为这是交替进行的。很容易得到本次进队的顺序是先左孩子还是先右孩子(因为这种也是交替的)。代码如下:
/**
* 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) {
if(root==null)
return new ArrayList<List<Integer>>();
TreeNode q=root;
Alist alist=new Alist();
alist.add(root);
List<List<Integer>> list=new ArrayList<List<Integer>>();
while(alist.one!=alist.two) {//两指针都到队尾了,跳出循环
int start=alist.getStart();
List<Integer> list1=new ArrayList<Integer>();
while(!alist.isgetOther()) {//两个指针相碰了,这一层的结束
q=alist.get();
list1.add(q.val);
if(!alist.flag) {//先左后右
if(q.left!=null)
alist.add(q.left);
if(q.right!=null)
alist.add(q.right);
}else {//先右后左
if(q.right!=null)
alist.add(q.right);
if(q.left!=null)
alist.add(q.left);
}
alist.change(); //一个节点处理完毕,改变节点
}
list.add(list1);//将这层的值放入整体的list中
alist.change2(start);//调整队尾队头
}
return list;
}
}
class Alist extends ArrayList{
int one=0;
int two=-1;
boolean flag=false;//用来控制本次是怎么进队
int getStart(){
return flag?two:one;
}
boolean isgetOther() {
return two==one;
}
void change() {
if(flag)
two--;
else
one--;
}
void change2(int index) {
if(flag)
{
one=this.size()-1;two=index;
}
else
{
two=this.size()-1;one=index;
}
flag=!flag;
}
TreeNode get() {
if(flag)
return (TreeNode)this.get(two);
else
return(TreeNode)this.get(one);
}
}