[面试] 手写题-数组转树

示例数据:

const arr = [{ id: 1, parentId: null, name: 'Root' },{ id: 2, parentId: 1, name: 'Child 1' },{ id: 3, parentId: 1, name: 'Child 2' },{ id: 4, parentId: 2, name: 'Grandchild 1' },
]

目标生成:

const tree = [{id: 1,name: 'Root',children: [{id: 2,name: 'Child 1',children: [{ id: 4, name: 'Grandchild 1', children: [] }],},{id: 3,name: 'Child 2',children: [],},],},
]

递归

function arrayToTree(arr, pid) {let res = [];arr.forEach((item) => {// parentId 等于null即为根节点if (item.parentId === pid) {// 递归查找当前节点的所有子节点const children = arrayToTree(arr, item.id);item.children = children;res.push(item);}});return res;
}let result = arrayToTree(arr, null)
console.log(result);

时间复杂度较高O(n^2)

Map

时间复杂度O(n)

function arrayToTree(arr) {const map = new Map();// 使用Map,查找父节点时间复杂度为O(1)const res = []; // 返回根节点数组// 第一次遍历:将所有节点存入Map(id作为键,节点对象作为值)for (const item of arr) {map.set(item.id, item);// 注意:这里存储的是原始对象的引用}// 第二次遍历:构建树结构for (const item of arr) {if (item.parentId=== null) { // 根节点res.push(item);} else { // 有父节点,// 查找当前节点的父节点const parent = map.get(item.parentId);if (!parent.children) {parent.children = [];}// 将当前节点添加到父节点的children数组parent.children.push(item);}}return res; 
}

避免修改原始数据的一版本

// 此版本通过创建节点副本避免修改原始数据,
function arrayToTree(arr) {const map = new Map();const res = [];// 第一步:创建所有节点的副本(含children属性)for (const item of arr) {// 使用展开运算符{...item}创建浅拷贝,避免直接修改原始数据map.set(item.id, { ...item, children: [] });}// 第二步:构建树结构for (const item of arr) {// 从Map获取当前节点对应的副本,注意:这里使用副本节点而非原始数据const node = map.get(item.id); if (item.parentId === null) { // 根节点res.push(node);} else {// 获取父节点副本const parent = map.get(item.parentId);// 将当前节点添加到父节点的children数组parent.children.push(node); }}  return res;
}

参考:

大厂JS笔试__数组与树互转

高频面试题:树结果转为数组,数组转为树(详细解答,性能提升之王)

大厂JS笔试__数组与树互转

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/912585.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/912585.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CertiK《Hack3d:2025年第二季度及上半年Web3.0安全报告》(附报告全文链接)

CertiK《Hack3d:2025年第二季度及上半年Web3.0安全报告》现已发布,报告显示:仅2025年上半年,因安全事件导致的损失接近25亿美元;截至目前,总损失已超过去年全年水平。整体来看,Web3.0安全形势依…

反向传播 梯度消失

反向传播 backpropagation 反向传播(Backpropagation) 是神经网络训练中的一种核心算法,用于通过计算误差并将其传播回网络,从而更新神经网络的参数。通过反向传播,网络能够在每次迭代中逐步调整其参数(例…

京东外卖服务商加入方案对比!选择本地生活服务商系统的优势,到底在哪?

自入局之日起,京东外卖似乎就一直热衷于给人惊喜: 先是在上线时规定了“2025年5月1日前入驻的商家,全年免佣金”和“仅限品质堂食商家入驻”; 再是宣布了要为外卖骑手缴纳五险一金,并承担其中的所有成本;…

【RTSP从零实践】4、使用RTP协议封装并传输AAC

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…

Bootstrap 安装使用教程

一、Bootstrap 简介 Bootstrap 是一个开源的前端框架,由 Twitter 开发,旨在快速开发响应式、移动优先的 Web 页面。它包含 HTML、CSS 和 JavaScript 组件,如按钮、导航栏、表单等。 二、Bootstrap 安装方式 2.1 使用 CDN(推荐入…

Java学习第二部分——基础语法

目录 一.数据类型 (一)数值类型(用于存储数字,包括整数和浮点数) 1. **整数类型** 2. **浮点类型** (二)非数值类型(非数值类型用于存储非数字数据) 1. **char** 2…

Redis分布式锁核心原理源码

文章目录 概述一、Redis实现分布式锁1.1、第一版1.2、第二版1.3、第三版1.3、第四版 二、Redisson实现分布式锁核心源码分析2.1、加锁核心源码2.2、锁续期核心源码2.3、重试机制核心源码2.4、解锁核心源码 总结 概述 传统的单机锁(Synchronized,Reentran…

关于vue2使用elform的rules校验

在使用vue2开发项目的时候使用element组件的el-form大多数情况都需要用到必填项校验 举个栗子&#xff1a; <el-form :model"ruleForm" :rules"rules" ref"ruleForm" label-width"100px" class"demo-ruleForm"><e…

langchain从入门到精通(二十六)——RAG优化策略(四)问题分解策略提升负责问题检索准确率

1. LangChain 少量示例提示模板 在与 LLM 的对话中&#xff0c;提供少量的示例被称为 少量示例&#xff0c;这是一种简单但强大的指导生成的方式&#xff0c;在某些情况下可以显著提高模型性能&#xff08;与之对应的是零样本&#xff09;&#xff0c;少量示例可以降低 Prompt…

Nuxt.js基础(Tailwind基础)

​​1. 按钮组件实现​​ ​​传统 CSS <!-- HTML --> <button class"btn-primary">提交</button><!-- CSS --> <style>.btn-primary {background-color: #3490dc;padding: 0.5rem 1rem;border-radius: 0.25rem;color: white;transi…

[C语言]存储结构详解

C语言存储结构总结 在C语言中&#xff0c;数据根据其类型和声明方式被存储在不同的内存区域。以下是各类数据存储位置的详细总结&#xff1a; 内存五大分区 存储区存储内容生命周期特点代码区(.text)程序代码(机器指令)整个程序运行期只读常量区(.rodata)字符串常量、const全…

【实战】 容器中Spring boot项目 Graphics2D 画图中文乱码解决方案

场景 架构&#xff1a;spring boot 容器技术&#xff1a;docker 服务器&#xff1a;阿里云 开发环境&#xff1a;windows10 IDEA 一、问题 服务器中出现Graphics2D 画图中文乱码 本地环境运行正常 二、原因 spring boot 容器中没有安装中文字体 三、解决方案 安装字体即可 …

深入浅出:Vue2 数据劫持原理剖析

目录 一、什么是数据劫持&#xff1f; 二、核心 API&#xff1a;Object.defineProperty 三、Vue2 中的数据劫持实现 1. 对象属性的劫持 2. 嵌套对象的处理 3. 数组的特殊处理 四、结合依赖收集的完整流程 五、数据劫持的局限性 六、Vue3 的改进方案 总结 一、什么是数…

数据湖 vs 数据仓库:数据界的“自来水厂”与“瓶装水厂”?

数据湖 vs 数据仓库&#xff1a;数据界的“自来水厂”与“瓶装水厂”&#xff1f; 说起“数据湖”和“数据仓库”&#xff0c;很多刚入行的朋友都会觉得&#xff1a; “听起来好高大上啊&#xff01;但到底有啥区别啊&#xff1f;是湖更大还是仓库更高端&#xff1f;” 我得说…

Node.js-path模块

Path 模块 path 模块提供了 操作路径 的功能&#xff0c;我们将介绍如下几个较为常用的几个 API ​​path.resolve([…paths]) 将路径片段​​解析为绝对路径​​&#xff08;从右向左拼接&#xff0c;遇到绝对路径停止&#xff09; // 若参数为空&#xff0c;返回当前工作目…

Java面试题029:一文深入了解MySQL(1)

欢迎大家关注我的专栏,该专栏会持续更新,从原理角度覆盖Java知识体系的方方面面。 一文吃透JAVA知识体系(面试题)https://blog.csdn.net/wuxinyan123/category_7521898.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=7521898&

vue3.0所采用得Composition Api与Vue2.XOtions Api有什么不同?

Vue 3.0 引入的 Composition API 相较于 Vue 2.x 的 Options API 有显著的不同。下面从几个方面对比这两者的差异&#xff1a; ✅ 1. 代码组织方式不同 Vue 2.x — Options API 使用 data、methods、computed、watch 等分散的选项组织逻辑。 每个功能点分散在不同的选项中&am…

【IP 潮玩行业深度研究与学习】

潮玩行业发展趋势分析&#xff1a;全球市场格局与中国政策支持体系 潮玩产业正经历从"小众收藏"到"大众情绪消费"的深刻转型&#xff0c;2025年中国潮玩市场规模已达727亿元&#xff0c;预计2026年将突破1100亿元&#xff0c;年复合增长率高达26%。这一千…

进程通信-消息队列

消息队列允许一个进程将一个消息发送到一个队列中&#xff0c;另一个进程从该队列中接收这个消息。 使用流程&#xff1a; 写端&#xff1a; 使用结构体 mq_attr 设置消息队列属性&#xff0c;有四个选项&#xff1a; long mq_flags; // 队列属性: 0 表示阻塞 long …

串行通信接口USART,printf重定向数据发送,轮询和中断实现串口数据接收

目录 UART通信协议的介绍 实现串口数据发送 CubeMX配置 printf重定向代码编写 实现串口数据接收 轮询方式实现串口数据接收 接收单个字符 接收不定长字符串&#xff08;接收的字符串以\n结尾&#xff09; 中断方式实现串口数据接收 CubeMX配置 UART中断方式接收数据…