当前位置: 首页 > news >正文

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

示例数据:

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.lryc.cn/news/576770.html

相关文章:

  • VS2022-动静态库
  • (LeetCode 面试经典 150 题 ) 134. 加油站 (贪心)
  • MATLAB GUI界面设计 第七章——高级应用
  • 大数据Hadoop之——安装部署hadoop
  • Wpf布局之StackPanel!
  • 【Java EE初阶 --- 多线程(进阶)】锁策略
  • Git常见使用
  • 现代 JavaScript (ES6+) 入门到实战(四):数组的革命 map/filter/reduce - 告别 for 循环
  • 【记录】Ubuntu创建新用户,并可远程连接
  • 【大语言模型入门】—— 浅析LLM基座—Transformer原理
  • 自然语言处理NLP期末复习
  • 解锁云原生微服务架构:搭建与部署实战全攻略
  • 小米路由器 AX3000T自定义子网掩码
  • 大模型小模型选型手册:开源闭源、国内国外全方位对比
  • AtCoder Beginner Contest 412
  • 2025.6GESP四级(编程题详解)
  • 基于云的平板挠度模拟:动画与建模-AI云计算数值分析和代码验证
  • 鸿蒙5:自定义构建函数
  • 提示技术系列——生成知识提示
  • HTTP中常见的Content-Type
  • 【HuggingFace】模型选型策略指南(读懂config.json)
  • RAG工作原理
  • 什么是MPC(多方安全计算,Multi-Party Computation)
  • LeetCode Hot 100 最大子数组和
  • HarmonyOS NEXT仓颉开发语言实战案例:小而美的旅行App
  • NLP文本增强——随机删除
  • HarmonyOS NEXT仓颉开发语言实战案例:健身App
  • 野生动物检测数据集介绍-5,138张图片 野生动物保护监测 智能狩猎相机系统 生态研究与调查
  • rabbitmq springboot 有哪些配置参数
  • ONLYOFFICE 协作空间 企业版使用秘籍-8.使用虚拟数据房间,处理机密文档更安全