【前端面试】七、算法-递归、拷贝等

news2025/1/24 11:35:52

目录

1.常考算法

2.遍历方法

3.链式调用

4.递归

5.拷贝和比较


1.常考算法

  1. 排序算法:快速排序、归并排序、堆排序等。

  2. 查找算法:二分查找、哈希表查找等。

  3. 动态规划:解决最优化问题,如斐波那契数列、最长公共子序列等。

  4. 图论算法:最短路径(Dijkstra、Floyd-Warshall)、拓扑排序等。

  5. 字符串处理:KMP算法、正则表达式匹配等。

2.遍历方法

数组break迭代器
for×
for...of
for... in×
forEach××
map××
while

3.链式调用

  • 数组的很多操作可以构成链式操作,类似这样的格式:…map().filter(…).sort(…).map(….)
  • 链式操作就是对象方法返回类型是自身的。比如map是属于数组的方法,它返回数组,所以构成了链式操作
  • 优势:语义清晰、思考方便,数据量小的时候很有用(<1W)
  • 问题:性能、空间

4.递归

  • 条件:递归通常需要初始条件和递归表达式
  • 阶乘:n! = n x (n-1) !   
     // 阶乘
    function factorial(n) {
      if (n === 1) return 1
      return n * factorial(n - 1)
    }
  • 斐波那契:f(1) = 1, f(2) = 1,f(n) = f(n-1) + f(n-2), n>2 
     // 斐波那契数列 1 1 2 3 5 8 13 21 34 55 89 144
    function fibonacci(n) {
      if (n === 1 || n === 2) return 1
      return fibonacci(n - 1) + fibonacci(n - 2)
    }

    // 从底端构造递归
    function fibonacci1(n) {
      let [a,b] = [1,1]
      for(let i = 3; i <= n; i++) {
        [a,b] = [b, a + b]
      }
      return b
    }
    // console.log('测试 fibonacci1=============');
    // console.log(fibonacci1(10));

    function fibonacci2(n) {
      return Array(n - 2).fill(0).reduce(([a,b],_) => {
        return [b, a + b]
      }, [1,1])[1]
    }
    // console.log('测试 fibonacci2=============');
    // console.log(fibonacci2(10));
  • DOM结点的绝对位置

offsetLeft、offsetRight相对于offsetParent的位置
Element.getBoundingClientRect()相对于视窗的位置,受滚动的影响

 // DOM节点的绝对位置
   function getLayout1(el) {
     if (!el) return;
     const layout = {
      width: el.offsetWidth,
      height: el.offsetHeight,
      top: el.offsetTop,
      left: el.offsetLeft
     }
     if(el.offsetParent) {
       const parentLayout = getLayout1(el.offsetParent)
       layout.top += parentLayout.top
       layout.left += parentLayout.left
     }
    return layout
   }

   function getLayout2(el) {
      if (!el) return;
      let left = el.offsetLeft
      let top = el.offsetTop
      let p = el.offsetParent
      while(p) {
        left += p.offsetLeft
        top += p.offsetTop
        p = p.offsetParent
      }
      return {
        width: el.offsetWidth,
        height: el.offsetHeight,
        top,
        left
      }
   }

5.拷贝和比较

push/pop/shift/unshift/splice:都在原始数据上进行修改

concat/slice/map/reduce:都会对原始数据进行浅拷贝

    // 递归实现深拷贝
    function deepClone(obj) {
      if (typeof obj !== 'object' || obj === null) return obj
      // const newObj = Array.isArray(obj) ? [] : {}
      // const newObj = obj instanceof Array ? [] : {}
      // const newObj = obj.constructor === Array ? [] : {}
      // const newObj = Object.prototype.toString.call([]) === '[object Array]' ? [] : {}
      const newObj = new obj.constructor()
      for(let key in obj) {
        if(obj.hasOwnProperty(key)) {
          newObj[key] = deepClone(obj[key])
        }
      }
      return newObj
    }

    // 测试用例  
    function testDeepClone() {  
      console.log("测试普通对象:");  
      const obj1 = { a: 1, b: { c: 2 } };  
      const clonedObj1 = deepClone(obj1);  
      console.assert(obj1 !== clonedObj1, "对象应该是不同的引用");  
      console.assert(obj1.b !== clonedObj1.b, "嵌套对象也应该是不同的引用");  
      console.assert(obj1.b.c === clonedObj1.b.c, "嵌套对象的属性值应该相等");  
      
      console.log("测试数组:");  
      const arr1 = [1, 2, [3, 4]];  
      const clonedArr1 = deepClone(arr1);  
      console.assert(arr1 !== clonedArr1, "数组应该是不同的引用");  
      console.assert(arr1[2] !== clonedArr1[2], "嵌套数组也应该是不同的引用");  
      console.assert(arr1[2][0] === clonedArr1[2][0], "嵌套数组的元素值应该相等");  
      
      console.log("测试特殊对象(Date):");  
      const date1 = new Date();  
      const clonedDate1 = deepClone(date1);  
      console.assert(date1 !== clonedDate1, "Date 对象应该是不同的引用");  
      console.assert(date1.getTime() === clonedDate1.getTime(), "Date 的时间戳应该相等");  
      
      // console.log("测试特殊对象(RegExp):");   // 失败 
      // const reg1 = /hello/g;  
      // const clonedReg1 = deepClone(reg1);  
      // console.assert(reg1 !== clonedReg1, "RegExp 对象应该是不同的引用");  
      // console.assert(reg1.source === clonedReg1.source && reg1.global === clonedReg1.global, "RegExp 的属性和标志应该相等");  
      
      // console.log("测试循环引用:");   // 失败 
      // const obj2 = {};  
      // obj2.self = obj2;  
      // const clonedObj2 = deepClone(obj2);  
      // console.assert(obj2 !== clonedObj2, "对象应该是不同的引用");  
      // console.assert(clonedObj2.self === clonedObj2, "循环引用应该被正确处理");  
      
      console.log("所有测试通过!");  
    }  
      
    // testDeepClone();

    // 深度比较
    function deepCompare(a,b){
      if (a === null || typeof a !== 'object' || b === null || typeof b !== 'object') {
        return a === b
      }
      // Object.getOwnPropertyDescriptors 方法会返回对象自身的所有属性描述符,包括不可枚举的属性
      const propsA = Object.getOwnPropertyDescriptors(a)
      const propsB = Object.getOwnPropertyDescriptors(b)
      if(Object.keys(propsA).length !== Object.keys(propsB).length) return false
      return Object.keys(propsA).every(key => deepCompare(a[key],b[key]))
    }
    // 测试用例  
    function testDeepCompare() {  
      console.log("测试基本相等性:");  
      console.assert(deepCompare(1, 1), "1 应该等于 1");  
      console.assert(!deepCompare(1, 2), "1 不应该等于 2");  
      console.assert(deepCompare(null, null), "null 应该等于 null");  
      console.assert(deepCompare(undefined, undefined), "undefined 应该等于 undefined");  
      console.assert(!deepCompare(null, undefined), "null 不应该等于 undefined");  
      
      console.log("测试对象比较:");  
      const obj1 = { a: 1, b: { c: 2 } };  
      const obj2 = { a: 1, b: { c: 2 } };  
      const obj3 = { a: 1, b: { c: 3 } };  
      console.assert(deepCompare(obj1, obj2), "obj1 应该等于 obj2");  
      console.assert(!deepCompare(obj1, obj3), "obj1 不应该等于 obj3");  
      
      console.log("测试数组比较:");  
      const arr1 = [1, 2, [3, 4]];  
      const arr2 = [1, 2, [3, 4]];  
      const arr3 = [1, 2, [3, 5]];  
      console.assert(deepCompare(arr1, arr2), "arr1 应该等于 arr2");  
      console.assert(!deepCompare(arr1, arr3), "arr1 不应该等于 arr3");  
      
      // console.log("测试循环引用(此实现可能无法正确处理):");  
      // const obj4 = {};  
      // obj4.self = obj4;  
      // const obj5 = {};  
      // obj5.self = obj5;  
      // 注意:此实现可能无法正确处理循环引用,因为它会陷入无限递归  
      // 这里我们假设它不会处理循环引用,并跳过这个测试  
      // console.assert(deepCompare(obj4, obj5), "循环引用对象应该相等(但这里不测试)");  
      
      console.log("所有测试通过!");  
    }  
      
    // testDeepCompare();

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

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

相关文章

8.3 day bug

bug1 文件名字写错了&#xff0c;找了半天bug原因 freecodecamp的致敬页的测试验证不通过bug 已经写了display: block;和max-width: 100% 以及通过margin: 0 auto;居中&#xff0c;可是却通不过验证 问了通义千问 通义帮我修改后的html代码为 <!DOCTYPE html> 2<h…

打扫朋友圈

我把上周写的一篇文章&#xff0c;发到了老家的一个群里&#xff0c;结果有个多年没联系的亲戚&#xff0c;立马私信给我说&#xff0c;让我不要在群里发&#xff0c;说我写的东西不行&#xff0c;他自己看了两行就看不下去了&#xff0c;然后给我讲了一堆大道理。 哎呦我去&a…

从零开始的CPP(34)——字符串乘法

给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 注意&#xff1a;不能使用任何内置的 BigInteger 库或直接将输入转换为整数。 示例 1: 输入: num1 "2", num2 "3" …

RAG 的优化进阶与引入 Reranker

引言 在简单的 RAG 系统中&#xff0c;通过结合检索和生成技术&#xff0c;已经可以显著提升了对复杂查询的响应质量。Reranker 作为 RAG 系统中一个关键的进阶组件&#xff0c;通过对原 RAG 中检索到的内容进行重新组织&#xff0c;可以进一步提高系统的准确性。 本文将深入…

vmware虚拟机linux服务器的IP需要重启才能生效问题

vmware虚拟机linux服务器的IP需要重启才能生效问题 问题说明处理办法关闭&禁用网络管理 再次重启linux服务器&#xff0c;IP显示正常 问题说明 用vmware虚拟的linux服务器&#xff0c;配置了静态IP&#xff0c;但是每次重启liunx&#xff0c;IP都不是设置的静态IP&#xf…

国外教育人工智能发展与应用

在全球化与信息化交织的时代背景下&#xff0c;人工智能正迅速推动教育发生颠覆性变革。从大洋彼岸到东方之滨&#xff0c;世界主要国家和组织正采取相关行动和策略&#xff0c;深度挖掘和释放教育AI的潜能。本文从政策支持、教育应用两个方面&#xff0c;聚焦“教育人工智能”…

centos 安装nacos

nacos官网下载安装包&#xff08;安装nacos之前&#xff0c;先下载安装好jdk&#xff09; 概览 | Nacos 官网 2.下载好nacos压缩包之后&#xff0c;上传到linux目录中&#xff08;在/opt/目录下建好一个文件夹&#xff09; 将nacos解压 uzip nacos-server-1.4.7.zip 进入naco…

【STM32系统】基于STM32设计的按键PWM控制舵机窗帘柜子门禁家居等控制系统——文末资料下载

演示 摘要 随着智能家居技术的不断发展&#xff0c;舵机在自动化家居设备中的应用变得越来越广泛。本文设计并实现了一种基于STM32单片机的按键PWM控制舵机系统。通过按键可以精确控制舵机角度&#xff0c;实现对窗帘、柜子、门禁等家居设备的智能化控制。系统采用STM32F10x系…

C# Unity 面向对象补全计划 七大原则 之 单一职责

本文仅作学习笔记与交流&#xff0c;不作任何商业用途&#xff0c;作者能力有限&#xff0c;如有不足还请斧正 本系列作为七大原则和设计模式的进阶知识&#xff0c;看不懂没关系 1.单一职责原则&#xff08;SRP&#xff09; 单一职责原则&#xff08;Single Responsibility P…

iPhone怎么大批量删除照片:释放你的存储空间

随着iPhone相机质量的提升&#xff0c;我们越来越倾向于使用手机捕捉生活中的每一个瞬间。不久后&#xff0c;我们就会发现手机内存充满了成千上万的照片&#xff0c;这不仅占用了大量的存储空间&#xff0c;也让照片的管理变得越来越困难。对于需要释放空间的用户来说&#xf…

谷粒商城实战笔记-125-全文检索-ElasticSearch-整合-SpringBoot整合high-level-client

文章目录 一&#xff0c;技术选型1. 通过 TCP 连接&#xff08;9300 端口&#xff09;2. 通过 HTTP 连接&#xff08;9200 端口&#xff09;3.最终选择 二&#xff0c;SpringBoot整合Elasticsearch-Rest-High-Level-Client1&#xff0c;新增模块gulimall-search1&#xff0c;添…

基于python旅游推荐系统(源码+论文+部署讲解等)

博主介绍&#xff1a;✌全网粉丝10W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 技术栈介绍&#xff1a;我是程序员阿龙&#xff…

【Hadoop-驯化】一文学会hadoop访问hdfs中常用命令使用技巧

【Hadoop-驯化】一文学会hadoop访问hdfs中常用命令使用技巧 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注&am…

MockingBird - 实时语音克隆 中文/普通话

文章目录 一、关于 MockingBird特性 二、安装1、通用配置2、M1芯片Mac环境配置&#xff08;Inference Time)2.1 安装PyQt52.2 安装pyworld和ctc-segmentation2.3 安装其他依赖2.4 运行 三、准备预训练模型1、使用数据集自己训练encoder模型 (可选)2、使用数据集自己训练合成器模…

41缺失的第一个正数【力扣】【C++】

题目描述 题目链接 给你一个未排序的整数数组 nums &#xff0c;请你找出其中没有出现的最小的正整数。 请你实现时间复杂度为 O(n) 并且只使用常数级别额外空间的解决方案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,0] 输出&#xff1a;3 解释&#xff1a;范围 [1,…

一篇文章让你搞懂原码,反码,补码!

目录 1.机器数和机器数真值 1.1机器数 1.2机器数的真值 2.原码&#xff0c;反码&#xff0c;补码的计算方法 2.1原码 2.2反码 2.3补码 3.为什么要使用反码和补码&#xff1f; 3.1原码不能让符号位参与运算的问题&#xff1a; 3.2为了解决原码作减法&#xff0c;引入…

【C语言】算法:二分查找

当我们想在一个有序的序列里面查找一个数字的时候&#xff0c;通常会想到使用循环遍历&#xff0c;也就是下面这种方法&#xff1a; 比如我们想在下面的数组里面找到7&#xff1a; int main() {int num 7;int arr[10] { 1,2,3,4,5,6,7,8,9,10 };for (int i 0; i < size…

在亚马逊云科技AWS上利用ElasticSearch和RAG搭建个性化推荐系统

简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍用当下热门的RAG和大语言模型&#xf…

ThreadLocal源码分析

1.前言 1.1 ThreadLocal基本原理 ThreadLocal 是 Java 中的一个非常有用的类&#xff0c;它提供了一种线程局部变量&#xff0c;即每个线程都可以访问到自己独立初始化过的变量副本&#xff0c;这个变量对其他线程是不可见的。最常见的用法就是用户请求携带用户ID请求某个接口…

机器学习 第9章-聚类

机器学习 第9章-聚类 9.1 聚类任务 在“无监督学习”(unsupervised learning)中&#xff0c;训练样本的标记信息是未知的&#xff0c;目标是通过对无标记训练样本的学习来揭示数据的内在性质及规律&#xff0c;为进一步的数据分析提供基础。此类学习任务中研究最多、应用最广…