两题连刷,教你学会二叉树的的层序遍历

479 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

两题连刷,教你学会二叉树的的层序遍历

[102] 二叉树的层序遍历

给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。

示例 1:

image.png

输入: 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

解题思路

什么是层序遍历?

即逐层地,从左到右访问所有节点

举个例子:

  • 假定我们给定一个二叉树(如下图) image.png
  • 当我们进行层序遍历的时候的 输出应该是【A,B,C,D,E,F,G,H,I,J,K】

解题难点

层序和前、中、后序遍历的解题思路其实都是差不多的,都是递归:先当前节点然后处理剩下的子节点。

但是不同的是,我们需要先处理完毕当前层的所有子节点。

所以在我们查询当前节点的时候,需要保存这个节点的左右子节点,然后等下一次的递归的时候处理 image.png

那么解决方法就很简单了:

直接上代码

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是数组,我们需要给他拆开来;剩下的思路就没有任何的差距

这就是一招鲜吃遍天???

image.png