前端工程师在算法面试中通常会遇到以下类型的题目,这些题目既考察基础算法能力,也结合前端特性。以下是常见题型及示例:
一、数组/字符串处理
-
两数之和
- 题目:找出数组中两数之和等于目标值的索引
- 解法:哈希表存储差值,时间复杂度 O(n)
const twoSum = (nums, target) => { const map = new Map(); for (let i = 0; i < nums.length; i++) { const complement = target - nums[i]; if (map.has(complement)) return [map.get(complement), i]; map.set(nums[i], i); } }; -
最长无重复子串
- 题目:求字符串中最长不重复字符的子串长度
- 解法:滑动窗口 + 哈希表,时间 O(n)
const lengthOfLongestSubstring = (s) => { let map = new Map(), max = 0, left = 0; for (let right = 0; right < s.length; right++) { if (map.has(s[right])) left = Math.max(left, map.get(s[right]) + 1); map.set(s[right], right); max = Math.max(max, right - left + 1); } return max; };
二、DOM 树与遍历算法
-
深度优先遍历 DOM 树
- 题目:实现 DFS 遍历 DOM 节点并返回所有标签名
function dfs(node, result = []) { result.push(node.tagName); for (const child of node.children) dfs(child, result); return result; } -
广度优先遍历 DOM 树
- 题目:按层级输出 DOM 节点标签名
function bfs(root) { const queue = [root], result = []; while (queue.length) { const node = queue.shift(); result.push(node.tagName); queue.push(...node.children); } return result; }
三、排序与搜索
-
手写快速排序
const quickSort = (arr) => { if (arr.length <= 1) return arr; const pivot = arr.pop(); const left = arr.filter(x => x <= pivot); const right = arr.filter(x => x > pivot); return [...quickSort(left), pivot, ...quickSort(right)]; }; -
实现数组的扁平化与去重
- 输入:
[1, [2, [3, 4]], 2]→ 输出:[1, 2, 3, 4]
const flattenAndUnique = (arr) => [...new Set(arr.flat(Infinity))].sort((a,b) => a - b); - 输入:
四、链表操作
-
反转链表
function reverseList(head) { let prev = null, curr = head; while (curr) { const next = curr.next; curr.next = prev; prev = curr; curr = next; } return prev; } -
判断环形链表(快慢指针)
const hasCycle = (head) => { let slow = head, fast = head; while (fast && fast.next) { slow = slow.next; fast = fast.next.next; if (slow === fast) return true; } return false; };
五、动态规划与贪心
-
爬楼梯问题
- 题目:每次爬 1 或 2 阶,到第 n 阶有多少种方法?
const climbStairs = (n) => { let [a, b] = [1, 1]; for (let i = 2; i <= n; i++) [a, b] = [b, a + b]; return b; }; -
买卖股票的最佳时机
- 题目:一次交易的最大利润
const maxProfit = (prices) => { let min = Infinity, max = 0; for (const price of prices) { min = Math.min(min, price); max = Math.max(max, price - min); } return max; };
六、设计类问题
-
实现 Promise.all
Promise.myAll = (promises) => { return new Promise((resolve, reject) => { let results = [], count = 0; promises.forEach((p, i) => { p.then(res => { results[i] = res; if (++count === promises.length) resolve(results); }).catch(reject); }); }); }; -
LRU 缓存机制
- 结合 Map 和双向链表实现 O(1) 的 get/put 操作。
七、其他高频题
- 有效的括号(栈的应用)
- 合并两个有序链表
- 二叉树的层序遍历
- 实现防抖(debounce)与节流(throttle)
- 千分位格式化数字(正则或数值处理)
考察重点
- 复杂度分析:时间/空间复杂度的计算与优化思路
- 代码简洁性:能否用 ES6+ 语法简化代码(如
Map、Set、解构赋值) - 边界处理:空输入、极端值、特殊数据结构的处理
- 前端结合点:如用算法优化 DOM 操作、处理虚拟 DOM 差异等
建议结合 LeetCode(标签:前端、算法)和《剑指 Offer》进行针对性练习,重点关注高频题目的多种解法。