js算法题解(第十九天)---LeetCode:102. 二叉树的层序遍历

237 阅读3分钟

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

前言

每天至少一道算法题,死磕算法

看到二叉树就比较兴奋,因为《labuladong算法小抄》上说过刷题一定要先刷二叉树

那么为什么要先刷二叉树呢,因为二叉树是最容易培养框架思维的,而且大部分算法技巧,本质上都是树的遍历问题

那么接下来一段时间我们就一起来探索二叉树的模板,多刷几道2叉树

Q:BFS和队列有什么关系?为什么BFS中常常有queue的影子?

A:

image.png

既然叫层序遍历,有时候你是不是要知道自己在第几层(好多题会这样考),那我们访问第一层,打个标记,这是第一层,访问完毕,然后第一层的数据出来,我们访问第二层,在打个标记,这是第二层,访问完毕,第二层的数据都出来,我们访问第三层...这种访问数据的结构很像队列,访问第一层,a入列,开始访问,发现a下面有b,b入列,a出列,开始访问第二层,发现b下面有三个c,d,e三个元素,那么c,d,e入列,b出列...所以这种访问的方式不就是队列么,有了队列我们可以更好的访问,更好的记录楼层

接下来开始做题

题目

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

 


示例 1:


![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/da41b645bd6749c49fe292d85b30103f~tplv-k3u1fbpfcp-watermark.image?)

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

输出:[[3],[9,20],[15,7]]

思路

二叉树的题目都有框架,我们做题的时候直接套用框架就可以了,但是一定要理解,然后在记忆

先上BFS的框架

function BFS(入口坐标) {
    const queue = [] // 初始化队列queue
    // 入口坐标首先入队
    queue.push(入口坐标)
    // 入口坐标是第一层也就是0,所以level从1开始,代表遍历第二层
    let level = 1;
    // 队列不为空,说明没有遍历完全
    while(queue.length) {
        // 当前queue的长度,一定要先声明长度,因为queue一直在变
        let length = queue.length;
        // for循环使当前层的都出列,下一层的都入列
        for(let i=0;i<length;i++){
            // 上面的i不要用,因为我们
            let node = queue.shift();
            // 从node上取出元素,放到queue队列中
            queue.push(取出的元素)
        }
        // 层数+1;
        level++;
    }
}

有了框架,我们写起来直接套框架就可以啦

var levelOrder = function(root) {
    // 如果入口是空的,那么直接返回空数组,无论是字符串,数组,链表,二叉树,首先要考虑为空的情况
    if(!root){
        return [];
    }
    // 初始化队列
    let queue = [];
    // 入口文件入列
    queue.push(root);
    // 要返回的结果,就是把每一层的数值以一个数组的形式返回
    // 第一个数组就是第一层的值
    let result = [[root.val]];
    // 定义楼层
    let level = 1;
    // 开始遍历队列中的数据
    while(queue.length){
        // 当前楼层的长度
        let length = queue.length;
        // 初始化当前楼层数组
        result[level] = [];
        // 遍历当前楼层元素
        for(let i=0;i<length;i++){
            // 取出元素
            let node = queue.shift();
            // 访问左侧元素
            if(node.left){
                // 存入当前楼层数值
                result[level].push(node.left.val);
                // 添加元素入队列
                queue.push(node.left);
            }

            // 访问右侧元素
            if(node.right){
                // 存入当前楼层数值
                result[level].push(node.right.val);
                // 添加元素入队列
                queue.push(node.right);
            }
        }
        // 如果当前楼层是空楼层,那么这层楼就不要了,是为了处理最后一层
        if(!result[level].length){
            result.pop();
        }
        // 访问下一层
        level++;
    }
    return result;

};

总结

掌握了层序遍历,那可了不得,二叉树的大门正在慢慢向你敞开

参考