一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
一.题目:
103. 二叉树的锯齿形层序遍历 给你二叉树的根节点
root,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
示例 1:
输入: root = [3,9,20,null,null,15,7]
输出: [[3],[20,9],[15,7]]
示例 2:
输入: root = [1]
输出: [[1]]
示例 3:
输入: root = []
输出: []
提示:
- 树中节点数目在范围
[0, 2000]内 -100 <= Node.val <= 100
二、思路分析:
这道题目跟我上篇文章的题目有点类似,不过这道题目相当于上篇文章的变体,因为要求我们按照锯齿形层序遍历,即每一层的层序遍历次序是不同的,第一层从左到右,第二层从右到左以此类推。所以这道题目我们的思路是:
- 是不是能够通过每一层的层数然后判断我们是从左子树出发还是右子树出发?显然这种方法时间复杂度爆炸,所有我们只需要建立一个改变方向的变量
flag,如果是-1的情况就需要从左往右遍历,这里我使用的是reverse函数直接反转暂存数组中的值同样可以达到效果。 - 循环里面的每一步都是弹出上一层的节点然后判断有无左右子树,如果有则加入,每次弹出操作时都需要将弹出的节点值推入暂存结果集中,等每一层循环完毕后再将暂存结果集推入结果集即可完成题目的要求。
三、代码:
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var zigzagLevelOrder = function(root) {
let res = []
if(!root) return res
let visited = [root]
let flag = 1
while(visited.length){
let len = visited.length
let temparr = []
for(let i=0 ; i<len ; i++){
let cur = visited.shift()
temparr.push(cur.val)
if(cur.left) visited.push(cur.left)
if(cur.right) visited.push(cur.right)
}
if(flag != 1) temparr.reverse()
flag = -flag
res.push(temparr)
}
return res
};
四、总结:
层序遍历尤其适合解决二叉树中每一层的相关问题,而且层次遍历的思路能够让我们更加清晰自己的思路,当然利用递归也能够解决这类问题,就是利用递归的时候需要我们自己注意我们定义的递归函数到底有什么意义。