持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
两题连刷,教你学会二叉树的的层序遍历
[102] 二叉树的层序遍历
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入: root = [3,9,20,null,null,15,7]
输出: [[3],[9,20],[15,7]]
示例 2:
输入: root = [1]
输出: [[1]]
示例 3:
输入: root = []
输出: []
提示:
- 树中节点数目在范围
[0, 2000]
内 -1000 <= Node.val <= 1000
解题思路
什么是层序遍历?
即逐层地,从左到右访问所有节点
举个例子:
- 假定我们给定一个二叉树(如下图)
- 当我们进行层序遍历的时候的 输出应该是【A,B,C,D,E,F,G,H,I,J,K】
解题难点
层序和前、中、后序遍历的解题思路其实都是差不多的,都是递归:先当前节点然后处理剩下的子节点。
但是不同的是,我们需要先处理完毕当前层的所有子节点。
所以在我们查询当前节点的时候,需要保存这个节点的左右子节点,然后等下一次的递归的时候处理
那么解决方法就很简单了:
直接上代码
var levelOrder = function (root) {
if (!root || root.length) return []
// 结果数组
const res = []
// 创建一个临时数组 存储需要弹出的节点
help([root], res)
return res
};
const help = (stack, res) => {
if (!stack || !stack.length) return
const temp = []
const subStack = [] // 存储子节点
for (let node of stack) {
temp.push(node.val)
node.left && subStack.push(node.left)
node.right && subStack.push(node.right)
}
if (temp.length) {
res.push(temp)
}
help(subStack, res)
}
解析:
Q:help函数的参数stack是什么意思?
A:stack是当前我们所在层的所有节点,是一个数组
Q:help函数的常量temp是什么意思?
A::temp是为了存储当前层的所有节点的数值
Q:help函数的常量subStack是什么意思?
A::subStack是为了存储当前层的所有节点的子节点,送给下一个help函数进行调用
在我们理解了,这一题之后 [107] 二叉树的层序遍历 II 也是手到擒来。
[107] 二叉树的层序遍历 II
给你二叉树的根节点 root
,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
解题
这题的解题思路和上一题完全一致,唯一不同的就是我们在 push 结果的时候,应该是往前插入,而不是往后插入
const help = (stack, res) => {
// ... 省略
if (temp.length) {
res.unshift(temp)
}
help(subStack, res)
}
进阶
甚至,我们可以根据前面两题的思路解决 [429] N 叉树的层序遍历
var levelOrder = function (root) {
if (!root) {
return []
}
const res = []
help([root], res)
return res
};
const help = (stack, res) => {
if (!stack || stack.length == 0) {
return
}
const temp = []
const subStack = []
for (const node of stack) {
temp.push(node.val)
node.children && subStack.push(...node.children)
}
res.push(temp)
help(subStack, res)
}
解析:
node.children && subStack.push(...node.children)
,children是数组,我们需要给他拆开来;剩下的思路就没有任何的差距
这就是一招鲜吃遍天???