一、前言
这题是二叉树的层序遍历的变种,需要将层序遍历结果反转。正常的层序遍历是从上往下打印,这题要求我们从下往上打印,我们可以先正常的层序遍历,然后将层序遍历的结果反转。
这里我将用两种方式来解这题-迭代、递归
二、题目描述
原谅我比较懒,我直接从leetcode截图,欲知更加清楚的描述,请看leetcode题目链接
三、解题
3.1 递归法
3.1.1 说明
- 递归函数的意义:层序遍历以root为根节点的二叉树
- 递归结束条件:节点为空
- 递归过程:层序遍历左子树、层序遍历右子树
3.1.2 代码
/**
* 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 代码
/**
* 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;
}
}