前端算法小白攻略44-leetcode(二叉树的层序遍历)

100 阅读2分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战

前言

今天我们是两道关于二叉树层序遍历的变型题,分别是107. 二叉树的层序遍历 II103. 二叉树的锯齿形层序遍历

题目描述

107. 二叉树的层序遍历 II

给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)

103. 二叉树的锯齿形层序遍历

给你二叉树的根节点 root ,返回其节点值的 锯齿形层序遍历 。(即先从左往右,再从右往左进行下一层遍历,以此类推,层与层之间交替进行)。

解题思路

image.png
对于上面这颗二叉树,如前面从上到下打印二叉树而言,打印结果为:

[
  [3],
  [9,20],
  [15,7]
]

第一题中自底向上的层序遍历打印结果为:

[
  [15,7]
  [9,20],
  [3],
]

第二题中锯齿形层序遍历打印结果为:

[
  [3],
  [20,9],
  [15,7]]

综上我们能够得出:第一题的自底向上的层序遍历只要对自上而下打印二叉树的结果进行整体翻转即可,而锯齿形层序遍历中假设根节点属于第0层,那么它的打印结果为自上而下打印二叉树的结果的奇数项里节点元素的翻转

开始解题

这里我们把两道题的解法放到一起,大家可自行选择使用

var levelOrderBottom = function(root) {
    let resArr = new Array();
    print(root, 0, resArr);
    
    // 二叉树的层序遍历
    for(let i = 0, j = resArr.length-1; i < j; i++, j--){  // i<j 中间一项不用动
        [resArr[i], resArr[j]] = [resArr[j], resArr[i]];   // 翻转二维数组的节点元素
    }
    
    // 锯齿形层序遍历
    // 定义k表示二叉树层数,k=0为第一层,锯齿形层序遍历处理的是奇数项,k从1开始
    for(let k = 1; k < resArr.length; k+=2) {  // k+=2奇数项表示处理奇数项
        for(let i = 0, j = resArr[k].length-1; i < j; i++, j--){  // i<j 中间一项不用动
            [resArr[k][i], resArr[k][j]] = [resArr[k][j], resArr[k][i]]; // 翻转第k层奇数层的所有元素
        }
    }
    return resArr;
};

var print = function(root, k, resArr) {
    if(!root) return null;
    if(k == resArr.length) resArr.push(new Array());  // 遍历的新的一层需要初始化创建一个二维数组元素的容器数组
    resArr[k].push(root.val);         // 处理完当前节点后,按照前序遍历的顺序处理左右子节点
    print(root.left, k+1, resArr);    // 左右子节点则为下一层即k+1层
    print(root.right, k+1, resArr); 
}