面试官:来道送分题

浅聊一下

在这些天的面试中,总结了一些送分的题目...

面试了这么多天,觉得一个人的力量还是太过薄弱,如果你和我一样想进大厂,欢迎掘友们私聊我交流面经(wechat: LongLBond)

深度优先遍历和广度优先遍历

通常在遍历一棵树的时候,我们会遇到DFS和BFS

DFS

DFS深度优先,我们很容易理解就是要先遍历到树的每个结点的最深处

js 复制代码
function dfs(node){
    console.log(node.value)
    for(let child of node){
        dfs(child)
    }
}
  1. 打印当前节点的值

  2. 遍历当前节点的每个子节点:

    • for(let child of node):这里使用了for...of语法来遍历当前节点的每个子节点。

    • 对于每个子节点,会递归调用dfs(child)函数:

      • 这样会先处理当前子节点,打印其值,然后继续深度优先搜索子节点的子节点,直到整个树结构被完全探索。

BFS

BFS广度优先遍历,按层级遍历,要实现层级遍历使用队列是再好不过的了...

js 复制代码
function bfs(root){
    let queue = [root]
    while(queue.length){
        const currentNode = queue.shift()
        console.log(currentNode.value)
        if(currentNode.children){
            currentNode.children.forEach(child=>{
                queue.push(child)
            })
        }
    }
}
  1. 首先维护一个队列,遍历队列,队列为空代表树已经遍历完成
  2. 根据队列先进先出,取出一个结点,打印值,并且将子结点依次存入队列
  3. 循环...

将列表组装成树形结构

这道题目考察的是一个开发能力

应用场景: 省县市选择、多级菜单

在前后端的数据流转时,后端返回的数据是一条一条的,使用select*获取数据,而这些数据的父子关系在返回数据的时候并没有提现,所以就需要我们进行一个列表组装成树形结构的操作...

数据:

js 复制代码
[
            {
                id: 1001,
                parentId: 0,
                name: "AA",
            },
            {
                id: 1002,
                parentId: 1001,
                name: "BB",
            },
            {
                id: 1003,
                parentId: 1001,
                name: "CC",
            },
            {
                id: 1004,
                parentId: 1003,
                name: "DD",
            },
            {
                id: 1005,
                parentId: 1003,
                name: "EE",
            },
            {
                id: 1006,
                parentId: 1002,
                name: "FF",
            },
            {
                id: 1007,
                parentId: 1002,
                name: "GG",
            },
            {
                id: 1008,
                parentId: 1004,
                name: "HH",
            },
            {
                id: 1009,
                parentId: 1005,
                name: "II",
            },
        ];

暴力解法

暴力一点,直接双层遍历找到父结点并且把自己塞进去

js 复制代码
function listToSimpleTree(data){
    const res = []
    data.forEach(item=>{
        const parent = data.find(node=>item.parentId === node.id )
        if(parent){
            parent.children = parent.children || []
            parent.children.push(item)
        }else{
            res.push(item)
        }       
    })
    return res
}

空间换时间

暴力解法的时间复杂度为O(n^2),可以通过空间换时间的方式来优化一下...

js 复制代码
function listToTree(data){
    const obj = {}
    data.forEach(item=>{
        obj[item.id] = item
    })
    const res = []
    data.forEach(item=>{
        const parent = obj[item.parentId]
        if(parent){
            parent.children = parent.children || []
            parent.children.push(item)
        }else{
            res.push(item)
        }
    })
    return res
}

先把每个item以键值对的方式存入obj中,那么就不用再遍历寻找父节点了...

递归

还可以使用递归实现

js 复制代码
function recursiveToTree(data){
            function loop(key){
                const arr = []
                data.forEach(item => {
                    if(item.parentId === key){
                        item.children = loop(item.id)
                        arr.push(item)
                    }
                })
                return arr
            }
            return loop(0)
        }
  1. 定义一个loop函数,接收一个key值
  2. 在loop函数中遍历data,找一下parentId为key的结点存入arr
  3. 在找到结点以后,再递归找到本结点的子结点,直到查找完全return arr
  4. 一级结点的父结点为0,所以直接返回loop(0)就可以

红绿灯

手写一个红绿灯,红绿黄三个灯依次亮起

js 复制代码
function red(){
    console.log('红');
}
function yellow(){
    console.log('黄');
}
function green(){
    console.log('绿');
}

function light(cb,wait){
   return new Promise((resolve)=>{
       setTimeout(()=>{
           cb();
           resolve();
       },wait)
   })
}

function lightStep(){
    Promise.resolve().then(()=>{
        return light(red,3000);
    }).then(()=>{
        return light(yellow,2000);
    })
    .then(()=>{
        return light(green,1000);
    }).finally(()=>{
       return lightStep() 
    })
}
lightStep()

思路非常简单,主要就是通过finally()一直重复调用...

结尾

掘友们还遇见过哪些送分题,来评论区说说...

相关推荐
用户831348593069825 分钟前
Vue3 事件:常用用法与开发高频坑点
前端·javascript·vue.js
xxwl58526 分钟前
第六章---计算几何
笔记·学习·算法
漫步人生走在路上1 小时前
用小语种SEO突破外贸B2B天花板:法语、德语市场的实测数据
开发语言·前端·javascript·人工智能·搜索引擎·ecmascript
Logic1011 小时前
C语言/数据结构二维数组题解:找出行列O个数均为偶数的格子——奇偶性预处理+二次遍历
c语言·数据结构·算法·二维数组·时间复杂度·动态内存分配·奇偶性
程序猿阿森1 小时前
【机器学习实战】朴素贝叶斯算法详解:从概率基础到商品评论情感分析
算法·机器学习·概率论
xxwl5852 小时前
区域赛算法模版第五章---数学与数论
c++·笔记·算法
看浪的路人2 小时前
第6讲:Agent 安全体系——Prompt 注入防御、工具调用审计与输出合规
人工智能·算法
ydjs678899-bot2 小时前
您的Next.js中间件匹配器配置可能会跳过您认为它保护的路由
开发语言·javascript·中间件
局部有解2 小时前
LeetCode Hot100 438 找到字符串中所有字母异位词
c++·算法·leetcode
Chengbei112 小时前
JsOwl|AI 赋能 JS 敏感信息扫描器,AST + 正则、source‑map 源码还原、登录态爬虫输出交互式 HTML 报告
开发语言·javascript·网络·人工智能·爬虫·网络安全·自动化