这个系列没啥花头,就是纯 leetcode 题目拆解分析,不求用骚气的一行或者小众取巧解法,而是用清晰的代码和足够简单的思路帮你理清题意。让你在面试中再也不怕算法笔试。
78. 二叉树的层序遍历 (binary-tree-level-order-traversal)
标签
- 二叉树的层序遍历
- 中等
题目
这里不贴题了,leetcode打开就行,题目大意:
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[9,20],
[15,7]
]
基本思路
这篇思路非常清晰,我不赘述了,看完给他点赞哈! 二叉树的层序遍历
BFS 是按层层推进的方式,遍历每一层的节点。题目要求的是返回每一层的节点值,所以这题用 BFS 来做非常合适。
关于 DFS / BFS 的相关内容 移步这篇哈 DFS + BFS
基本步骤
BFS 需要用队列作为辅助结构,下面是简单说明步骤
- 我们先将根节点放到队列中,第一层有一个节点,队列长度为 1 ,这个长度也就表示该层有几个节点
- 取出队列头部node 第一次就是根 值放进该层list 并把它左右子树入队列,(其实就是记录这层有多少岔道)
- 把该层list 放进结果数组就行了,一层的遍历就完成了,下面第二层同样的操作就行了,继续重复
实现上来说2层循环,外层循环一次代表一层,得到一个列表,放进结果数组,内部循环循环该层队列中的每个节点,并把这层节点的左右子树推到下一层队列中。(因为循环次数为当前层节点个数,所以后面推进去的是下一层循环才会用到)
写法实现
const levelOrderBFS = function(root) {
let resList = []
let queue = []
if (root !== null) {
queue.push(root)
}
while(queue.length > 0) {
let curLevelList = []
let levelSize = queue.length
while(levelSize > 0) {
// 队列先进先出,用shift从队列头取出node并访问
let node = queue.shift()
// 把node推进每层的list
curLevelList.push(node.val)
// 当前层list长度 - 1
levelSize--
// 这个node的左右子树就是下一层的node节点
// 所以分别把当前取出的node的左右子树推进一个临时列表,作为下层循环的队列
// 层次遍历从左到右,先进左子树后进右子树
if(node.left !== null) {
queue.push(node.left)
}
if(node.right !== null) {
queue.push(node.right)
}
}
// 把当前层list推到结果列表
resList.push(curLevelList)
}
return resList
};
79. 二叉树的锯齿形层序遍历 (binary-tree-zigzag-level-order-traversal)
标签
- 二叉树的层序遍历
- 中等
题目
这里不贴题了,leetcode打开就行,题目大意:
给定一个二叉树,返回其节点值的锯齿形层序遍历。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层序遍历结果:
[
[3],
[20,9],
[15,7]
]
基本思路
上面一题的变种,思想几乎一模一样,只不过给加个状态位,平时工作中类似打个补丁。直接看代码。
写法实现
const levelOrderBFS = function(root) {
let resList = []
let queue = []
// 添加的就是这个状态位 是否从左边开始
let isLeftStart = true
if (root !== null) {
queue.push(root)
}
while(queue.length > 0) {
let curLevelList = []
let levelSize = queue.length
while(levelSize > 0) {
let node = queue.shift()
// 其实就是这,原来都是 push,现在需要加上进列表方向
if (isLeftStart) {
curLevelList.push(node.val);
} else {
curLevelList.unshift(node.val);
}
levelSize--
if(node.left !== null) {
queue.push(node.left)
}
if(node.right !== null) {
queue.push(node.right)
}
}
// 下一层反向
isLeftStart = !isLeftStart
resList.push(curLevelList)
}
return resList
};
另外向大家着重推荐下这位大哥的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列
今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦
搜索我的微信号infinity_9368,可以聊天说地
加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我
presious tower shock the rever monster,我看到就通过,暗号对不上不加哈,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧