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

news2024/11/27 17:35:33

前言

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

 🍅 个人主页:南木元元

现在前端的面试中,算法出现的频率越来越高了,大厂更是必考算法 。本文就来分享一下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;
}

结语

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

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

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

相关文章

北邮复试刷题103. 二叉树的锯齿形层序遍历

103. 二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a;输入&#xff1a…

Acwing---846. 树的重心

树的重心 1.题目2.基本思想3.代码实现 1.题目 给定一颗树&#xff0c;树中包含 n n n 个结点&#xff08;编号 1 ∼ n 1∼n 1∼n&#xff09;和 n − 1 n−1 n−1 条无向边。 请你找到树的重心&#xff0c;并输出将重心删除后&#xff0c;剩余各个连通块中点数的最大值。 …

Kafka King 推荐一款漂亮、现代、实用的kafka客户端

Kafka King 一个漂亮、现代、实用的kafka客户端&#xff0c;使用python flet、flutter构建。 Github主页&#xff1a;https://github.com/Bronya0/Kafka-King 下载&#xff1a;https://github.com/Bronya0/Kafka-King/releases 功能清单 查看集群节点列表创建主题&#xf…

【动态规划】【C++算法】1563 石子游戏 V

作者推荐 【数位dp】【动态规划】【状态压缩】【推荐】1012. 至少有 1 位重复的数字 本文涉及知识点 动态规划汇总 LeetCoce:1563 石子游戏 V 几块石子 排成一行 &#xff0c;每块石子都有一个关联值&#xff0c;关联值为整数&#xff0c;由数组 stoneValue 给出。 游戏中…

前端常见的设计模式

说到设计模式&#xff0c;大家想到的就是六大原则&#xff0c;23种模式。这么多模式&#xff0c;并非都要记住&#xff0c;但作为前端开发&#xff0c;对于前端出现率高的设计模式还是有必要了解并掌握的&#xff0c;浅浅掌握9种模式后&#xff0c;整理了这份文章。 六大原则&…

Leetcode-103. 二叉树的锯齿形层序遍历

这个年和树过不去啦啦啦&#xff01; 题目&#xff1a; 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&…

【C++】:位图、布隆过滤器、哈希分割

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家解读一下位图、布隆过滤器、哈希分割&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精…

Kingfisher — 快速灵活的公共数据库下载工具

Kingfisher — 快速灵活的公共数据库下载工具 Kingfisher 是一个快速灵活的程序&#xff0c;用于从公共数据库下载序列文件 (及其元数据注释)&#xff0c;包括 European Nucleotide Archive (ENA)&#xff0c; NCBI SRA&#xff0c;亚马逊 AWS 和谷歌云。它的输入是一个或多个 …

Fluke ADPT 连接器新增对福禄克万用 Fluke 17B Max 的支持

所需设备&#xff1a; 1、Fluke ADPT连接器&#xff1b; 2、Fluke 17B Max&#xff1b; Fluke 17B Max拆机图&#xff1a; 显示界面如下图&#xff1a; 并且可以将波形导出到EXCEL: 福禄克万用表需要自己动手改造&#xff01;&#xff01;&#xff01;

2024年【危险化学品经营单位安全管理人员】考试报名及危险化学品经营单位安全管理人员考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位安全管理人员考试报名是安全生产模拟考试一点通总题库中生成的一套危险化学品经营单位安全管理人员考试资料&#xff0c;安全生产模拟考试一点通上危险化学品经营单位安全管理人员作业手机同步练习…

C#(C Sharp)学习笔记_循环语句【七】

什么是循环语&#xff1f; 循环语句是由循环体及循环的终止条件两部分组成的。 在不少实际问题中有许多具有规律性的重复操作&#xff0c;因此在程序中就需要重复执行某些语句。一组被重复执行的语句称之为循环体&#xff0c;能否继续重复&#xff0c;决定循环的终止条件。循环…

摸索设计模式的魅力:从策略模式看软件设计的智慧-灵活应对变化的艺术

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 一、案例场景1.1 一坨坨代码实现1.2 存在的问题 二、使用策略模式解决问题2.1 使用策略模式重构代码2.2 克服了问题 三、模式讲解3.1 结构图及说明3.2 实现步骤和注意事项3.3 适用场景 四、优势和局限性4.1 优势4.2 局…

IP地址+子网掩码+CIDR学习笔记

目录 一、IP地址 1、表示方法&#xff1a; 2、特殊IP地址 二、子网掩码 1、判断网络位和主机位 2、子网划分 三、无分类编址CIDR 1、CIDR路由汇聚 汇聚规则&#xff1a; 汇聚ID&#xff1a; 2、最佳路由匹配原则 一、IP地址 1、表示方法&#xff1a; 机器中存放的…

【报告解析】OpenAI Sora视频模型官方报告全解析 | 效果,能力以及基本原理

省流版 1 核心数据处理将视频数据整合成一个一个的Patch&#xff0c;方便统一训练数据&#xff0c;利用扩散Transformer架构 2 功能效果除了可以实现基础的文生视频外&#xff0c;实际上还有非常惊艳的视频延展&#xff0c;视频编辑&#xff0c;视频连接等多种功能&#xff0…

防御保护--防病毒网关

网络安全之防病毒网关--恶意软件 按照传播方式分类 病毒 病毒 --- 一种基于硬件和操作系统的程序&#xff0c;具有感染和破坏能力&#xff0c;这与病毒程序的结构有关。病毒攻击的宿主程序是病毒的栖息地&#xff0c;它是病毒传播的目的地&#xff0c;又是一个感染的出…

Python算法题集_二叉树的层序遍历

Python算法题集_二叉树的层序遍历 题102&#xff1a;二叉树的层序遍历1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【DFS递归】2) 改进版一【BFS迭代】3) 改进版二【BFS迭代循环】 4. 最优算法 本文为Python算法题集之一的代码示例 题102&am…

变分自编码器(VAE)PyTorch Lightning 实现

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

Tcl 过程

一个Tcl过程就是Tcl脚本定义的一个命令。可以使用proc命令定义新的过程。Tcl还提供了处理变量作用域的特殊命令&#xff0c;这些命令允许使用引用而非值传递参数&#xff0c;并能把新的Tcl控制结构实现为过程。 一、proc与return 过程由proc命令创建, 其中参数{a b} 中的大括…

【Win10 触摸板】在插入鼠标时禁用触摸板,并在没有鼠标时自动启用触摸板。取消勾选连接鼠标时让触摸板保持打开状态,但拔掉鼠标后触摸板依旧不能使用

出现这种问题我的第一反应就是触摸板坏了&#xff0c;但是无意间我换了一个账户发现触摸板可以用&#xff0c;因此推断触摸板没有坏&#xff0c;是之前的账户问题&#xff0c;跟系统也没有关系&#xff0c;不需要重装系统。 解决办法&#xff1a;与鼠标虚拟设备有关 然后又从知…

【解决(几乎)任何机器学习问题】:超参数优化篇(超详细)

这篇文章相当长&#xff0c;您可以添加至收藏夹&#xff0c;以便在后续有空时候悠闲地阅读。 有了优秀的模型&#xff0c;就有了优化超参数以获得最佳得分模型的难题。那么&#xff0c;什么是超参数优化呢&#xff1f;假设您的机器学习项⽬有⼀个简单的流程。有⼀个数据集&…