前端面试算法手撕全解(高频真题+标准答案)

摘要:本文汇总前端面试中 95% 的高频手撕算法真题,覆盖数组、字符串、递归、动态规划、工程工具及模拟手写六大方向。每道题均配有业务场景、解题思路与可直接运行的完整代码,并附面试话术,帮助读者快速背诵默写、从容应对笔试与手撕环节。

前端面试算法手撕全解(高频真题+标准答案)

前言

前端面试算法不考困难算法、不考复杂数据结构 ,全部集中在:数组、字符串、递归、遍历、模拟、简单DP、工程工具手写 。本文档汇总95% 前端手撕真题,每道题包含:场景、思路、完整可运行代码、复杂度分析、面试话术,可直接背诵默写。

阅读建议:先通读「一、面试特点」建立全局认知,再按「九、刷题优先级」的顺序逐题攻克。每道题建议先自己手写一遍,再对照标准答案查漏补缺,最后用「八、四段式答题法」口头复述一遍,做到"写得对、讲得清"。

一、前端算法面试特点(必看)

  • 重点:实用性算法,全部来自业务开发 + 笔试真题

  • 核心能力:遍历、递归、条件判断、数据格式化、边界处理

  • 手撕评分标准:代码完整、无BUG、能处理边界、能讲清思路、知道业务场景

二、数组高频算法(最常考)

解题思路 :利用 Set 天然去重特性,一行代码搞定;filter + indexOf 通过判断元素首次出现位置是否等于当前索引来去重,原理清晰;Map 写法利用 map.has() 判断是否已存在,效率更高。

复杂度分析:三种写法时间复杂度均为 O(n),空间复杂度均为 O(n)。

面试话术:"去重我一般先答 Set 最简写法,再补充 filter + indexOf 讲原理,最后用 Map 体现对引用类型和效率的考虑,形成梯度回答。"

解题思路:遍历数组,遇到子数组就递归展开并拼接结果,遇到普通元素直接 push,直到所有层级都被展开。

复杂度分析:时间复杂度 O(n),其中 n 为展开后所有元素的个数;空间复杂度 O(n)(递归调用栈深度取决于嵌套层级)。

面试话术 :"扁平化考察递归思想,我会先写递归版本,再提一句可以用 arr.flat(Infinity) 一行实现,体现对原生 API 的熟悉。"

解题思路 :求和用 reduce 累加,简洁且性能好;最大值用 Math.max 配合展开运算符,注意空数组会返回 -Infinity,可加默认值兜底。

复杂度分析:两者时间复杂度均为 O(n),空间复杂度 O(1)。

面试话术 :"求和与最大值是 reduce 和展开运算符的经典应用,我会顺带提一句边界处理------空数组时 Math.max(...[]) 返回 -Infinity,实际开发要加默认值。"

解题思路 :用 Map 记录已出现过的 key 值,filter 遍历时只保留第一次出现的元素,实现按指定字段去重。

复杂度分析:时间复杂度 O(n),空间复杂度 O(n)。

面试话术 :"对象去重是业务里最高频的场景,我会强调用 Map 而不是 Set,因为 Map 可以按任意字段(如 id)去重,更灵活。"

三、字符串高频算法

1. 字符串反转

场景:笔试基础题、密码反转、文本处理

javascript 复制代码
function reverseStr(str) {
  return str.split('').reverse().join('');
}

2. 回文字符串判断

定义:正读、反读完全一致

javascript 复制代码
function isPalindrome(str) {
  return str === reverseStr(str);
}

3. 统计字符串出现最多字符

场景:文本统计、关键词分析

javascript 复制代码
function getMaxChar(str) {
  const obj = {};
  let maxNum = 0;
  let maxChar = '';
  for (let char of str) {
    obj[char] = obj[char] ? obj[char] + 1 : 1;
    if (obj[char] > maxNum) {
      maxNum = obj[char];
      maxChar = char;
    }
  }
  return { maxChar, maxNum };
}

四、递归经典面试题(前端必考)

1. 递归深拷贝(终极手写)

业务场景:复杂表单数据备份、树形结构复制、状态缓存、防止原数据污染

面试亮点:处理基础类型、数组、对象、日期、正则,边界齐全

javascript 复制代码
function deepClone(obj) {
  // 1. 基础类型 / null 直接返回
  if (obj === null || typeof obj !== 'object') return obj;

  // 2. 处理特殊引用类型
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);

  // 3. 创建对应容器
  const newObj = Array.isArray(obj) ? [] : {};

  // 4. 递归遍历
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepClone(obj[key]);
    }
  }
  return newObj;
}

2. 递归遍历树形结构

场景:后台菜单、权限树、分类树、树形筛选

javascript 复制代码
// 遍历树形数据,执行回调
function traverseTree(list, callback) {
  list.forEach(item => {
    callback(item);
    if (item.children && item.children.length) {
      traverseTree(item.children, callback);
    }
  });
}

五、动态规划 & 笔试经典题

1. 最大连续子数组和(LeetCode简单经典)

场景:前端笔试高频压轴简单题

javascript 复制代码
function maxSubArray(nums) {
  let max = nums[0];
  let sum = 0;
  for (let i = 0; i < nums.length; i++) {
    // 要么单独当前数,要么累加之前
    sum = Math.max(sum + nums[i], nums[i]);
    max = Math.max(max, sum);
  }
  return max;
}

2. 斐波那契数列(优化版)

考点:递归、缓存优化、避免爆栈

javascript 复制代码
// 迭代优化(推荐,无栈溢出)
function fib(n) {
  if (n <= 2) return 1;
  let a = 1, b = 1;
  for (let i = 3; i <= n; i++) {
    [a, b] = [b, a + b];
  }
  return b;
}

六、前端工程算法(面试必手撕)

1. 防抖函数

场景:搜索框联想、输入框校验、窗口 resize、表单实时校验

核心:频繁触发重置计时,只执行最后一次

javascript 复制代码
function debounce(fn, delay = 500) {
  let timer = null;
  return function(...args) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, delay);
  }
}

2. 节流函数

场景:按钮防重提交、滚动加载、轮播、高频点击

核心:固定时间内只执行一次

javascript 复制代码
function throttle(fn, delay = 1000) {
  let flag = true;
  return function(...args) {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn.apply(this, args);
      flag = true;
    }, delay);
  }
}

七、高频模拟手写(伪算法,前端超高频)

1. 手写 call / apply / bind

javascript 复制代码
// 手写call
Function.prototype.myCall = function(context, ...args) {
  context = context || window;
  context.fn = this;
  const res = context.fn(...args);
  delete context.fn;
  return res;
};

// 手写apply
Function.prototype.myApply = function(context, args = []) {
  context = context || window;
  context.fn = this;
  const res = context.fn(...args);
  delete context.fn;
  return res;
};

// 手写bind
Function.prototype.myBind = function(context, ...args) {
  return (...newArgs) => this.myCall(context, ...args, ...newArgs);
};

2. 手写 Promise 简易版

javascript 复制代码
class MyPromise {
  constructor(executor) {
    this.status = 'pending';
    this.value = null;
    this.reason = null;
    this.onFulfilled = [];
    this.onRejected = [];

    const resolve = (val) => {
      if (this.status !== 'pending') return;
      this.status = 'fulfilled';
      this.value = val;
      this.onFulfilled.forEach(fn => fn());
    };

    const reject = (err) => {
      if (this.status !== 'pending') return;
      this.status = 'rejected';
      this.reason = err;
      this.onRejected.forEach(fn => fn());
    };

    executor(resolve, reject);
  }

  then(resolveFn, rejectFn) {
    if (this.status === 'fulfilled') resolveFn(this.value);
    if (this.status === 'rejected') rejectFn(this.reason);
    if (this.status === 'pending') {
      this.onFulfilled.push(() => resolveFn(this.value));
      this.onRejected.push(() => rejectFn(this.reason));
    }
  }
}

八、算法面试通用答题模板(背诵)

四段式答题法

  1. 题意分析:简单说明题目要实现的效果

  2. 解题思路:遍历/递归/双指针/动态规划

  3. 核心关键点:边界处理、终止条件、去重、状态保存

  4. 业务场景:对应项目中真实使用位置

九、前端算法刷题优先级(速成顺序)

  1. 防抖、节流、深拷贝 (必问)

  2. 数组去重、扁平化、对象去重 (最高频)

  3. 字符串操作、递归树遍历 (常规笔试)

  4. 简单DP、斐波那契、最大子数组 (拔高笔试)

  5. 手写call/apply/bind/Promise (中高级必问)

相关推荐
tangguofeng1 小时前
基于分治策略的循环赛日程表问题的思路讲解
算法
起个名字费劲死了2 小时前
VisionMaster集成深度学习算法(基础狗)
人工智能·深度学习·算法
lengxuenong2 小时前
枚举例题分析
c++·算法·青少年编程
Navigator_Z2 小时前
LeetCode //C - 1269. Number of Ways to Stay in the Same Place After Some Steps
c语言·算法·leetcode
2601_965742222 小时前
短视频脚本创作方法分享:本地生活类账号的起步思路
大数据·人工智能·算法·ai·新媒体运营·生活
55873生态系统手记2 小时前
读完 55873 资产钱包的技术栈,我重新理解了 "合规钱包" 应该长什么样
算法·架构
旋生万物2 小时前
素数螺旋映射 $z_n=n^{1+i}$ 的角分布统计检验与零模型对比
大数据·前端·人工智能·算法·云原生·螺旋生成论·螺旋相位
HRTOS2 小时前
HRTOS Shell继续完善:优化printf缓冲区与字符串越界保护,国庆后随新版本更新
运维·单片机·嵌入式硬件·算法·51单片机
邵奈一3 小时前
当沉香之乡遇上 Seed-2.1-pro:我用 AI 给村子做了一个数字门面
算法·架构
海天一色y3 小时前
图像分割全解析:从经典算法到深度学习的原理与实战(Python + MATLAB)
python·深度学习·算法