【面试】盘点10个高频的前端算法题,你全都会了吗?

前言

 📫 大家好,我是南木元元,热爱技术和分享,欢迎大家交流,一起学习进步!

 🍅 个人主页:南木元元

现在前端的面试中,算法出现的频率越来越高了,大厂更是必考算法 。本文就来分享一下10个常见的前端算法题,重要的地方已添加注释,如有不正确的地方,欢迎多多指正。


目录

1.合并两个有序数组

2.两数之和

3.三数之和

4.反转链表

5.全排列

6.有效的括号

7.二叉树的中序遍历

8.翻转二叉树

9.K个一组翻转链表

10.最长递增子序列

结语


1.合并两个有序数组

题目:给定两个非递减的有序数组nums1和nums2,合并nums2到nums1中,使合并后的数组同样按非递减顺序排列。

示例:

来源:LeetCode第88题

代码实现:

//方法1:将nums2放到nums1的尾部,然后直接对整个数组进行排序
var merge = function (nums1, m, nums2, n) {
  nums1.splice(m, n, ...nums2);
  nums1.sort((a, b) => a - b);
};

//方法2:逆向双指针,从后往前遍历
var merge = function (nums1, m, nums2, n) {
  let i = m - 1,
    j = n - 1,
    k = m + n - 1;
  while (i >= 0 || j >= 0) {
    if (i < 0) {
      nums1[k--] = nums2[j--];
    } else if (j < 0) {
      nums1[k--] = nums1[i--];
    } else if (nums1[i] <= nums2[j]) {
      nums1[k--] = nums2[j--];
    } else {
      nums1[k--] = nums1[i--];
    }
  }
  return nums1;
};

2.两数之和

题目:给定一个数组nums和一个目标值target,在数组中找出和为目标值的两个数,并返回下标。

示例:

来源:LeetCode第1题

代码实现:

// 哈希法,利用map
var twoSum = function (nums, target) {
  let map = new Map();
  // 遍历当前元素,并在map中寻找是否有匹配的key
  for (let i = 0; i < nums.length; i++) {
    if (map.has(target - nums[i])) {
      return [i, map.get(target - nums[i])];
    } else {
      // 没找到与当前匹配的元素,就把当前元素及对应下标加入map
      map.set(nums[i], i);
    }
  }
};

3.三数之和

题目:给你一个包含 n 个整数的数组 nums,判断nums中是否存在三个元素a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

示例:

来源:LeetCode第15题

代码实现:

// 双指针法
var threeSum = function (nums) {
  let res = [];
  //排序
  nums.sort((a, b) => a - b);
  for (let i = 0; i < nums.length; i++) {
    //如果当前第一个数大于0直接返回res
    if (nums[i] > 0) {
      return res;
    }
    //对第一个元素去重
    if (i > 0 && nums[i] === nums[i - 1]) {
      continue;
    }
    let l = i + 1;
    let r = nums.length - 1;
    while (l < r) {
      if (nums[i] + nums[l] + nums[r] > 0) {
        r--;
      } else if (nums[i] + nums[l] + nums[r] < 0) {
        l++;
      } else {
        res.push([nums[i], nums[l], nums[r]]);
        // 对第2、3个元素去重
        while (l < r && nums[l] === nums[l + 1]) {
          l++;
        }
        while (l < r && nums[r] === nums[r - 1]) {
          r--;
        }
        l++;
        r--;
      }
    }
  }
  return res;
};

4.反转链表

题目:给你一个单链表的头节点head,反转单链表。

示例:

来源:LeetCode第206题

代码实现:

// 1.双指针法,只需要改变链表的next指针的指向
var reverseList = function(head) {
    let p = null;
    let q = head;
    let tmp = null; //保存下一个节点
    while(q) {
        tmp = q.next;
        q.next = p;
        p = q;
        q = tmp;
    }
    return p;
};

// 2.递归法
var reverseList = function(head) {
    var reverse = function(p, q) {
        if(q === null) {
            return p;
        }
        let tmp = q.next;
        q.next = p;
        p = q;
        return reverse(p, tmp); //注意这里必须return
    }
    return reverse(null, head);
};

5.全排列

题目:给定一个没有重复数字的序列,返回其所有可能的全排列。

示例:

来源:LeetCode第46题

实现代码:

// 回溯
var permute = function (nums) {
  let res = [];
  let path = [];
  var bt = function (used) {
    if (path.length === nums.length) {
      res.push([...path]);
      return;
    }
    for (let i = 0; i < nums.length; i++) {
      //used数组,记录此时path里已经选择的元素,一个排列里一个元素只能使用一次
      if (used[i] === 1) {
        continue;
      }
      path.push(nums[i]);
      used[i] = 1;
      bt(used);
      used[i] = 0;
      path.pop();
    }
  };
  bt([]);
  return res;
};

6.有效的括号

题目:给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

示例:

来源:LeetCode第20题

实现代码:

var isValid = function (s) {
  let stack = [];
  for (let i = 0; i < s.length; i++) {
    if (s[i] === "(") {
      stack.push(")");
    } else if (s[i] === "{") {
      stack.push("}");
    } else if (s[i] === "[") {
      stack.push("]");
    } else {
      //栈为空,说明多了右括号
      if (stack.length === 0 || stack.pop() !== s[i]) {
        return false;
      }
    }
  }
  //遍历结束栈还有元素,说明多了左括号
  return stack.length !== 0 ? false : true;
};

7.二叉树的中序遍历

题目:给定一个二叉树的根节点root,返回它的中序遍历。

示例:

来源:LeetCode第94题

代码实现:

// 1.递归
法var preorderTraversal = function (root) {
  let res = [];
  var dfs = function (root) {
    if (!root) {
      return;
    }
    dfs(root.left); //左
    res.push(root.val); //中
    dfs(root.right); //右
  };
  dfs(root);
  return res;
};

// 2.迭代法(重点)
var inorderTraversal = function (root) {
  if (!root) {
    return [];
  }
  let res = [];
  let stack = [];
  //定义一个指针,指向当前遍历节点
  let cur = root; 
  while (cur || stack.length) {
    if (cur) {
      //一直遍历到左下
      stack.push(cur);
      cur = cur.left;
    } else {
      cur = stack.pop();
      res.push(cur.val);
      cur = cur.right;
    }
  }
  return res;
};

8.翻转二叉树

题目:给你一棵二叉树的根节点root,翻转这棵树,并返回其根节点。

示例:

来源:LeetCode第102题

代码实现:

// 1.递归,先交换根节点左右子树,再分别对左右子树进行处理
var invertTree = function (root) {
  if (!root) {
    return root;
  }
  let tmp = root.left;
  root.left = root.right;
  root.right = tmp;
  invertTree(root.left);
  invertTree(root.right);
  return root;
};

// 2.迭代
var invertTree = function(root) {
    let stack = [];
    if(root == null) {
        return root;
    }
    stack.push(root);
    while(stack.length != 0) {
        let node = stack.pop();
        if(node != null) {
            if(node.right) {
                stack.push(node.right); 
            }
            if(node.left) {
                stack.push(node.left);  
            }
            stack.push(node);   
            stack.push(null);
        } else {
            let cur = stack.pop();  
            //每遍历一个节点,就交换它的左右子树
            [cur.left, cur.right] = [cur.right, cur.left];  
        }
    }
    return root;
};

9.K个一组翻转链表

题目:给你一个链表的头节点head,每k个节点一组进行翻转,返回修改后的链表。

示例:

来源:LeetCode第25题

代码实现:

var reverse = function (head, tail) {
  let prev = tail.next;
  let p = head;
  while (prev !== tail) {
    let tmp = p.next;
    p.next = prev;
    prev = p;
    p = tmp;
  }
  return [tail, head];
};
var reverseKGroup = function (head, k) {
  let vnode = new ListNode(0, head);
  let pre = vnode;
  while (head) {
    let tail = pre;
    // 查看剩余部分长度是否大于等于 k
    for (let i = 0; i < k; i++) {
      tail = tail.next;
      if (!tail) {
        return vnode.next;
      }
    }
    let tmp = tail.next;
    //反转每个子链表
    [head, tail] = reverse(head, tail);
    // 把子链表重新接回原链表
    pre.next = head;
    tail.next = tmp;
    pre = tail;
    head = tmp;
  }
  return vnode.next;
};

10.最长递增子序列

题目:给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

示例:

来源:LeetCode第300题

代码实现:

var lengthOfLIS = function(nums) {
    let dp = new Array(nums.length).fill(1);
    for(let i = 1; i < nums.length; i++) {
        for(let j = 0; j < i; j++) {
            if(nums[i] > nums[j]) {
                dp[i] = Math.max(dp[i], dp[j] + 1);
            }
        }
    }
    return Math.max(...dp);
};

题目扩展:给你一个整数数组 nums ,找出其最长严格递增子序列。

示例:

实现代码:

function lengthOfLIS(nums) {
  if (!nums.length) return [];
  let dp = new Array(nums.length).fill(1);
  for (let i = 0; i < nums.length; i++) {
    for (let j = 0; j < i; j++) {
      if (nums[j] < nums[i]) {
        dp[i] = Math.max(dp[i], dp[j] + 1);
      }
    }
  }
  //最长递增子序列的长度
  let max = Math.max(...dp); 

  let result = [];
  //倒序遍历,每次根据当前长度去获取数组中对应下标的值放入结果数组
  for (let i = max; i >= 1; i--) {
    // 找到符合条件最后一项的下标,这样才能保证数组的顺序是正确的
    let index = dp.lastIndexOf(i); 
    // 存储对应的值,插入结果数组的最前面
    result.unshift(nums[index]); 
    // 对dp进行截取,保证只取最大项之前的数据
    dp.length = index + 1; 
  }
  return result;
}

结语

🔥如果此文对你有帮助的话,欢迎💗关注、👍点赞、⭐收藏、✍️评论,支持一下博主~ 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GPIO八种工作模式

目录 一、推挽输出 二、开漏输出 三、复用推挽输出 四、复用开漏输出 五、浮空输入 六、上拉输入 七、下拉输入 八、模拟输入 GPIO八种配置模式&#xff0c;原理和使用场景&#xff0c;硬件原理如下图&#xff1a; 一、推挽输出 1、 原理 当控制栅极为低电平时&#x…

【Visual Studio】使用空格替换制表符

环境 VS版本&#xff1a;VS2013 问题 如何生成空格替换制表符&#xff1f; 步骤 1、菜单 工具->选项&#xff0c;文本编辑器->C/C->制表符&#xff0c;选择【插入空格】。

free pascal:fpwebview 组件通过 JSBridge 调用本机TTS

从 https://github.com/PierceNg/fpwebview 下载 fpwebview-master.zip 简单易用。 先请看 \fpwebview-master\README.md cd \lazarus\projects\fpwebview-master\demo\js_bidir 学习 js_bidir.lpr &#xff0c;编写 js_bind_speak.lpr 如下&#xff0c;通过 JSBridge 调用本…

php基础学习之可变函数(web渗透测试关键字绕过rce于回调函数)

可变函数 看可变函数的知识点之前&#xff0c;蒟蒻博主建议你先去看看php的可变变量&#xff0c;会更加方便理解&#xff0c;在本篇博客中的第五块知识点->php基础学习之变量-CSDN博客 描述 当一个变量所保存的值刚好是一个函数的名字&#xff08;由函数命名规则可知该值必…

挑战杯 python区块链实现 - proof of work工作量证明共识算法

文章目录 0 前言1 区块链基础1.1 比特币内部结构1.2 实现的区块链数据结构1.3 注意点1.4 区块链的核心-工作量证明算法1.4.1 拜占庭将军问题1.4.2 解决办法1.4.3 代码实现 2 快速实现一个区块链2.1 什么是区块链2.2 一个完整的快包含什么2.3 什么是挖矿2.4 工作量证明算法&…

精炼爆炸性新闻!OpenAI发布革命性AI视频生成模型Sora:实现长达60秒的高清视频创作「附AIGC行业系统搭建」

在人工智能领域&#xff0c;每一次技术革新都引领着未来的发展方向。OpenAI&#xff0c;作为全球领先的人工智能研究机构&#xff0c;再次证明了其在推动AI技术革新方面的领导地位。近日&#xff0c;OpenAI宣布推出了一款革命性的AI视频生成模型——Sora&#xff0c;这一大胆的…

Java实现实现自动化pdf打水印小项目 使用技术pdfbox、Documents4j

文章目录 前言源码获取一、需求说明二、 调研pdf处理工具word处理工具 三、技术栈选择四、功能实现实现效果详细功能介绍详细代码实现项目目录WordUtilsMain类实现部分&#xff1a;第一部分Main类实现部分&#xff1a;第二部分Main类实现部分&#xff1a;第三部分 资料获取 前言…

算法详解(力扣141——环形链表系列)

博主ID&#xff1a;代码小豪 文章目录 环形链表环形链表的性质分析快慢指针法指针的追及相遇问题 环形链表&#xff08;2&#xff09; 环形链表 先来看看环形链表的原题&#xff1a; 中间的部分叙述有点繁杂&#xff0c;简单来概括就是&#xff0c;假如有一个节点&#xff0c…

SAP PP学习笔记- 豆知识01 - 怎么查询既存品目

SAP系统当中已经有哪些品目要怎么查询呢&#xff1f; 1&#xff0c;MM60 品目一览 这里可以输入Plant&#xff0c;然后可以查询该工厂的所有品目。 2&#xff0c;SE16 > MARA MARA 品目一般Data&#xff0c;存放的是品目基本信息。 如果要查询该品目属于哪个Plant&#x…

【研究生复试】计算机软件工程人工智能研究生复试——资料整理(速记版)——计算机网络

1、JAVA 2、计算机网络 3、计算机体系结构 4、数据库 5、计算机租场原理 6、软件工程 7、大数据 8、英文 自我介绍 2. 计算机网络 1. TCP如何解决丢包和乱序&#xff1f; 序列号&#xff1a;TCP所传送的每段数据都有标有序列号&#xff0c;避免乱序问题发送端确认应答、超时…

[01] Vue2学习准备

目录 vue理解创建实例插值表达式 {{}}响应式特性 vue理解 Vue.js 是一套构建用户界面的渐进式框架。 Vue 只关注视图层&#xff0c; 采用自底向上增量开发的设计。 Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。 创建实例 准备容器 <div id…

问题:如果要编辑建好的建筑和空间,需要在分级按钮( )和细分操作按钮楼层下,才能选中建筑物和空间; #微信#媒体#其他

问题&#xff1a;如果要编辑建好的建筑和空间&#xff0c;需要在分级按钮&#xff08; &#xff09;和细分操作按钮楼层下&#xff0c;才能选中建筑物和空间&#xff1b; A、楼层 B、规划图 C、全景 D、建筑物 参考答案如图所示

JVM(3)高级篇

1 GraalVM 1.1 什么是GraalVM GraalVM是Oracle官方推出的一款高性能JDK&#xff0c;使用它享受比OpenJDK或者OracleJDK更好的性能。 GraalVM的官方网址&#xff1a;https://www.graalvm.org/ 官方标语&#xff1a;Build faster, smaller, leaner applications。 更低的CPU、内…

Midjourney提示词风格调试测评

在Midjourney中提示词及风格参数的变化无疑会对最终的作品产生影响&#xff0c;那影响具体有多大&#xff1f;今天我我们将通过一个示例进行探究。 示例提示词&#xff1a; 计算机代码海洋中的黄色折纸船&#xff08;图像下方&#xff09;风格参考:金色长发的女人&#xff0c…

vue3-应用规模化-路由和状态

客户端 vs. 服务端路由 服务端路由指的是服务器根据用户访问的 URL 路径返回不同的响应结果。当我们在一个传统的服务端渲染的 web 应用中点击一个链接时&#xff0c;浏览器会从服务端获得全新的 HTML&#xff0c;然后重新加载整个页面。 然而&#xff0c;在单页面应用中&…

电商+支付双系统项目------简介

电商支付双系统项目是一个综合性的项目&#xff0c;旨在建立一个完善的电商系统和独立的支付系统&#xff0c;以满足中国日益增长的电商交易需求并提供多样化、安全可靠的支付方式。随着中国电商行业的快速发展&#xff0c;电商平台需要具备高效、可靠的功能&#xff0c;而独立…

中国比特币矿工的新根据地:埃塞俄比亚

原文标题&#xff1a;《Chinese Bitcoin Miners Find a New Crypto Haven in Ethiopia》 撰文&#xff1a;David Pan、Fasika Tadesse&#xff0c;彭博社 编译&#xff1a;Carl&#xff0c;Techub News 中国比特币矿工的新根据地&#xff1a;埃塞俄比亚 去年春天&#xff0c…

蓝桥杯电子类单片机提升三——NE555

目录 单片机资源数据包_2023 一、NE555和定时器工作模式 1.NE555的介绍 2.定时器的计数模式 二、NE555频率读取代码的实现 1.定时器0初始化 2.通过读取TH0和TL0来读取频率 3.通过中断读取频率 三、完整代码演示 通过读取TH0和TL0来读取频率 main.c 通过中断读取频…

领导力提升,才是高绩效的关键

作为企业的CEO或团队管理者&#xff0c;在日常的团队管理工作中无论是领导力还是执行力&#xff0c;都是非常重要的。在领导力的提升方面&#xff0c;我们可以通过一整套方案来进行&#xff0c;包括如何设定目标&#xff0c;动机刺激、任务拆解、鼓励参与、责任承担、建立制度、…

NLP_ChatGPT的RLHF实战

文章目录 介绍小结 介绍 ChatGPT 之所以成为ChatGPT&#xff0c;基于人类反馈的强化学习是其中重要的一环。而ChatGPT 的训练工程称得上是复杂而又神秘的&#xff0c;迄今为止&#xff0c;OpenAl也没有开源它的训练及调优的细节。 从 OpenAl已经公开的一部分信息推知&#xff…