给定一个二叉树,返回其节点值的锯齿形层次遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
例如:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回锯齿形层次遍历如下:
[
[3],
[20,9],
[15,7]
]
思路:
还记得层序遍历吗?用一个队列来实现,先将根节点入队列,然后当队列不为空时循环,出队列节点,将这个节点的左右子结点入队列,直到队列为空。
本题是锯齿形,第一层从左往右,第二层从右往左。
因此必须设置一个当前遍历方向的变量:leftToRight = true(初始为第一行从左往右)
使用栈stack来实现(不得不说JavaScript里面队列也好、栈也好,都是数组而已)。
对于从左往右的层,需要先加左子节点,后加右子节点;对于从右往左,反之,先右后左。
举例说明:
1
/ \
2 3
/ \ / \
4 5 6 7
访问根节点,此时
保存节点的队列 stack = [2, 3]
结果数组 result = [[1]]
leftToRight = true;
栈先出 3 再出 2,因此 3 的左右子节点必须先右再左,第三层才能以 7、6、5、4 的顺序入栈,出栈的顺序才能刚好是从左往右的 4、5、6、7。
不多说,看代码
/** * Definition for a binary tree node. * function TreeNode(val) { * this.val = val; * this.left = this.right = null; * } */
/** * @param {TreeNode} root * @return {number[][]} */
var zigzagLevelOrder = function(root) {
if (!root) return [];
let leftToRight = true;
let stack = [];
let result = [];
let p = root;
stack.push(p)
while (stack.length) {
let len = stack.length;
let temp = [];
let result_temp = [];
while(len) {
p = stack.pop();
result_temp.push(p.val);
if (leftToRight) {
if (p.left) temp.push(p.left)
if (p.right) temp.push(p.right)
} else {
if (p.right) temp.push(p.right)
if (p.left) temp.push(p.left)
}
len--;
}
stack = temp;
leftToRight = !leftToRight;
result.push(result_temp)
}
return result;
};