【路飞】 32 - II. 从上到下打印二叉树 II、32 - I. 从上到下打印二叉树、 III. 从上到下打印二叉树 III、107. 二叉树的层序遍历 I

151 阅读2分钟

一.#### 32 - II. 从上到下打印二叉树 II 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行。

 

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

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

思路:这题的解题思路是,定义一个变量k代表的是每个节点应该存在第几个数组里,ans数据结构是[[],[],[]],代码如下:

* @param {TreeNode} root
 * @return {number[][]}
 */
var levelOrder = function(root) {
    if(! root) return [];
    let ans = [];
    //默认k等于0
    return _levelOrder(root,0,ans)
};

var _levelOrder = function(root,k,ans){
    if(!root) return;
    //ans默认是[],所以需要给ans主动保存一个数组,需要ans.push([]),这样就是[[]],方便ans里的字迹操作,不然不能试用push()
    if(k === ans.length) ans.push([]);
    //k标识的是将节点存在在第几个子节点里
    ans[k].push(root.val);
    //遍历左边节点,告诉存在第几个节点
    _levelOrder(root.left,k + 1,ans);
    //遍历右边节点,保持同一级的节点储存在同一个子集里
    _levelOrder(root.right,k + 1,ans);
    return ans;
}

二.#### 32 - I. 从上到下打印二叉树

从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回:

[3,9,20,15,7]

思路:这题比上一题稍微难些,是建立在上一题的基础上得到结构,先将每一层的节点保存在一个数组里,然后将数组[[],[],[]]通过循环变成[1,2,3,4,5],代码如下:

var levelOrder = function(root) {
    if(!root) return [];
    let ans = [];
    //定义一个变量接受将同一级的节点保存在一个数组里的数据
    let ansAll =  __levelOrder(root,0,ans);
    //变化后德邦数组
    let ansNew = [];
    for(let i = 0; i < ansAll.length; i ++){
        for(let j = 0; j < ansAll[i].length; j ++){
            ansNew.push(ansAll[i][j]);
        }
    }
    return ansNew;
};

var __levelOrder = function(root,k,ans){
    if(! root) return;
    //判断当前数组是否存在,不存在就造一个,跟上面一样
    if(k === ans.length) ans.push([]); 
    ans[k].push(root.val);
    __levelOrder(root.left,k + 1,ans);
    __levelOrder(root.right,k + 1,ans);
    return ans;
}

三.#### 32 - III. 从上到下打印二叉树 III

请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印,第三行再按照从左到右的顺序打印,其他行以此类推。

例如:
给定二叉树: [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回其层次遍历结果:

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

思路:这题也是建立在第一题的基础上,先将每一级的数组保存在同一个数组,然后然根据%2来判断是从左到右还是还是从右到左遍历,%2 如果等于0就是左到右,不需要处理,不等于0就需要从后往前遍历储存,代码如下:

var levelOrder = function(root) {
    if(!root) return [];
    let ans = [];
    //定义一个变量接受将同一级的节点保存在一个数组里的数据
    let ansAll = _levelOrder(root,0,ans);
    let ansNew = [];
    for(let i = 0; i < ansAll.length; i ++){
        if(i % 2 !== 0){
            ansNew.push([]);
            for(let j = ansAll[i].length - 1;j >= 0; j --){
                ansNew[i].push(ansAll[i][j])
            }
        }else{
            ansNew[i] = ansAll[i]
        }
        
    }
    return ansNew;
};

var _levelOrder = function(root,k,ans){
    if(!root) return;
    if(k === ans.length) ans.push([]);
    ans[k].push(root.val)
    _levelOrder(root.left,k + 1,ans);
    _levelOrder(root.right,k + 1,ans);
    return ans;
}

//注释上面都有,这里就不添加了

四.#### 二叉树的层序遍历 II

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

输入: root = [3,9,20,null,null,15,7]
输出: [[15,7],[9,20],[3]]

示例 2:

输入: root = [1]
输出: [[1]]

示例 3:

输入: root = []
输出: []

思路:思路跟上面差不多,直接上上代码了,代码如下:

var levelOrderBottom = function(root) {
    if(!root) return [];
    let ans = [];
    let ansAll = _levelOrder(root,0,ans);
    let j = ansAll.length -1;
    for(let i = 0; i < ansAll.length && i < j; i ++){
        let val = ansAll[i];
        ansAll[i] = ansAll[j];
        ansAll[j] = val;
        j --;
    }
    return ansAll;
};

var _levelOrder = function(root,k,ans){
    if(!root) return;
    if(k === ans.length) ans.push([]);
    ans[k].push(root.val);
    _levelOrder(root.left,k + 1,ans);
    _levelOrder(root.right,k + 1,ans);
    return ans;
}