leetcodeNo.103 二叉树的锯齿形层次遍历
1.题目描述:
给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7],
#输出:
返回锯齿形层序遍历如下:
[[3],[20,9],[15,7]]
2.解题思路
问题是基于二叉树层次遍历的衍生遍历方法。关于二叉树的遍历方法,主要分为先序遍历、中序遍历、后序遍历以及层次遍历。
层次遍历,顾名思义就是按照二叉树的层次开始遍历,本题描述为锯齿形层次遍历,每一层的遍历方向都和上一层相反。我们利用队列来辅助进行层次遍历,通过变量deep来控制当前遍历层次的深度(deep从0开始计数)。deep是偶数的时候,从左往右遍历,根据队列先进先出(FIFO)的原则,将每次遍历的结果通过尾插法插入到 List 里,deep是奇数时,从右往左遍历,通过头插法(每次数据都插入到 index = 0 的位置)插入到List里。
另一个问题:
如何控制使得每次都刚好遍历一层。使用变量 vol (根结点,第0层的 vol为1)来存储每一层的容量。这样通过一个for循环就可以保证每次遍历都是一层。
代码逻辑
/* 初始化变量
* // 层次遍历
* while(队列非空){
* // 遍历该层
* // 方法:
* // 取出队列信息
* // 根据deep值选择头插或者尾插
* // 将取出节点的叶子结点存入队列
* // 更新vol、deep
* }
*/
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> ans = new ArrayList<>();
if(root == null) { return ans; }
int deep = 0;
int vol = 1; // 记录容量
Queue<TreeNode> q = new LinkedList<>();
q.add(root);
while(!q.isEmpty()){
List<Integer> tmpTraMsg = new ArrayList<>();
Queue<TreeNode> tmpQ = new LinkedList<>();
int tmpVol = 0;
// 将下一层的信息录入到q,更新下一层的vol,更新这一层的信息
for(int i = 0; i < vol; i++){
TreeNode tmpNode = q.remove();
if(tmpNode.left != null){
q.add(tmpNode.left);
tmpVol++;
}
if(tmpNode.right != null){
q.add(tmpNode.right);
tmpVol++;
}
if(deep % 2 == 0){
// 正向遍历,尾插
tmpTraMsg.add(tmpNode.val);
}else{
// 反向遍历,头插
tmpTraMsg.add(0,tmpNode.val);
}
}
deep++;
ans.add(tmpTraMsg);
vol = tmpVol;
}
return ans;
}