用JavaScript刷leetcode第107题-二叉树的层序遍历Ⅱ

144 阅读2分钟

一、前言

这题是二叉树的层序遍历的变种,需要将层序遍历结果反转。正常的层序遍历是从上往下打印,这题要求我们从下往上打印,我们可以先正常的层序遍历,然后将层序遍历的结果反转。
这里我将用两种方式来解这题-迭代、递归

二、题目描述

原谅我比较懒,我直接从leetcode截图,欲知更加清楚的描述,请看leetcode题目链接

image.png

三、解题

3.1 递归法

3.1.1 说明

  • 递归函数的意义:层序遍历以root为根节点的二叉树
  • 递归结束条件:节点为空
  • 递归过程:层序遍历左子树、层序遍历右子树

3.1.2 代码

git代码链接

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
const levelOrderBottom = function(root) {
  // 结果数组
  const res = [];
  // 递归函数
 
  __levelOrderBottom(root, 0, res);

  // 翻转数组
  reverseArr(res);

  // 返回结果数组
  return res;
};

/**
 * @params root 节点
 * @params level 二维数组中外层数组下标
 * @params res 结果数组
 */
function __levelOrderBottom (root, level, res) {
  // 递归结束条件
  if(root === null) return;

  // 将节点的值放到结果数组中(二维数组,外层对应数的层数、内层放树每层节点的val)
  if(res.length === level) res.push([]);
  res[level].push(root.val);

  // 递归层序遍历左子树
  __levelOrderBottom(root.left, level + 1, res);
  // 递归层序遍历右子树
  __levelOrderBottom(root.right, level + 1, res);

}

/**
 * @params arr 待翻转数组
 */
function reverseArr(arr) {
  let i = 0, j = arr.length - 1;
  while(i < j) {
    [arr[i], arr[j]] = [arr[j], arr[i]];
    ++i, --j;
  }
}

3.2 迭代法

3.2.1 说明

  • 需要维护一个队列,存节点的val和当前节点所在层数
  • 节点出队,记录val到结果数组,并将其孩子(左右子节点)入队列

3.2.2 代码

git代码链接

/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {number[][]}
 */
const levelOrderBottom = function(root) {
  //  结果数组
  const res = [];

  // 如果是空树,返回res
  if(root === null) return res;

  // ********************* 代码到了这里说明树不是空树 ***************************

  // 队列(存树每层的节点)
  const queue = []
  // 初始化树,树第一层节点入队
  queue.push({node: root, level: 0});
  
  // 当前节点出队、当前节点的孩子节点入队
  while(queue.length) {
    // 出队
    const {node, level} = queue.shift();
    // 讲出队节点的val放到结果数组中
    if(res.length === level) res.push([]);
    res[level].push(node.val);

    // 出队节点的孩子节点入队
    if(node.left) queue.push({node: node.left, level: level + 1});
    if(node.right) queue.push({node: node.right, level: level + 1});
  }

  // 翻转结果数组
  reverseArr(res);

  // 返回结果数组
  return res;
}


function reverseArr(arr) {
   for(let i = 0, j = arr.length - 1; i < j; ++i, --j) {
     const temp = arr[i];
     arr[i] = arr[j];
     arr[j] = temp;
   }
 }