尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

前端算法实战:高频面试题解析与最优解法

前端算法实战:高频面试题解析与最优解法 1. 前端算法实战从零手撕高频面试题作为一名经历过多次大厂面试的前端工程师我深知算法能力在前端面试中的重要性。很多人认为前端不需要算法但现实是各大厂的前端岗位面试中算法题占比越来越高。今天我就来分享几个前端面试中最常考的算法题带你从零理解解题思路掌握最优解法。2. 无重复字符的最长子串2.1 问题分析给定一个字符串找出其中不含有重复字符的最长子串的长度。例如输入abcabcbb输出3abc输入bbbbb输出1b2.2 滑动窗口解法最优解法是滑动窗口双指针算法时间复杂度O(n)var lengthOfLongestSubstring function(s) { const charIndexMap new Map(); let left 0; let maxLength 0; for (let right 0; right s.length; right) { const currentChar s[right]; if (charIndexMap.has(currentChar) charIndexMap.get(currentChar) left) { left charIndexMap.get(currentChar) 1; } charIndexMap.set(currentChar, right); maxLength Math.max(maxLength, right - left 1); } return maxLength; };2.3 关键点解析charIndexMap记录字符最后出现的位置左指针移动只有当重复字符在当前窗口内时才移动窗口长度计算right - left 1注意事项处理abba这类情况时左指针不能回退必须确保left只向右移动3. 比较版本号3.1 问题描述比较两个版本号version1和version2如果version1 version2返回1如果version1 version2返回-1否则返回03.2 拆分补零解法var compareVersion function(version1, version2) { const v1Arr version1.split(.); const v2Arr version2.split(.); const maxLen Math.max(v1Arr.length, v2Arr.length); for (let i 0; i maxLen; i) { const num1 i v1Arr.length ? parseInt(v1Arr[i], 10) : 0; const num2 i v2Arr.length ? parseInt(v2Arr[i], 10) : 0; if (num1 num2) return 1; if (num1 num2) return -1; } return 0; };3.3 核心技巧split(.)正确拆分版本号parseInt自动忽略前导零补零处理短版本号缺失部分视为04. 合并两个有序数组4.1 逆向双指针解法从后往前合并避免覆盖nums1的元素var merge function(nums1, m, nums2, n) { let p1 m - 1; let p2 n - 1; let p m n - 1; while (p1 0 p2 0) { nums1[p--] nums1[p1] nums2[p2] ? nums1[p1--] : nums2[p2--]; } while (p2 0) { nums1[p--] nums2[p2--]; } };4.2 关键点三指针初始化p1指向nums1有效末尾p2指向nums2末尾从后往前填充避免元素覆盖处理剩余元素只需处理nums2剩余情况5. 有效的括号5.1 栈的应用var isValid function(s) { const bracketMap { ): (, }: {, ]: [ }; const stack []; for (let char of s) { if (char in bracketMap) { if (stack.length 0 || stack.pop() ! bracketMap[char]) { return false; } } else { stack.push(char); } } return stack.length 0; };5.2 注意事项右括号映射使用对象快速查找对应左括号栈空检查遇到右括号时栈不能为空最终栈检查遍历结束后栈必须为空6. 字符串相加6.1 模拟手工加法var addStrings function(num1, num2) { let i num1.length - 1; let j num2.length - 1; let carry 0; const result []; while (i 0 || j 0 || carry 0) { const digit1 i 0 ? Number(num1[i--]) : 0; const digit2 j 0 ? Number(num2[j--]) : 0; const sum digit1 digit2 carry; result.push(sum % 10); carry Math.floor(sum / 10); } return result.reverse().join(); };6.2 关键步骤从末尾开始相加模拟手工计算处理进位carry记录进位值结果反转因为是从个位开始存储7. 两数之和7.1 哈希表最优解var twoSum function(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); } return []; };7.2 性能对比方法时间复杂度空间复杂度暴力法O(n²)O(1)哈希表法O(n)O(n)8. 全排列8.1 回溯算法var permute function(nums) { const result []; const path []; const used new Array(nums.length).fill(false); const backtrack () { if (path.length nums.length) { result.push([...path]); return; } for (let i 0; i nums.length; i) { if (used[i]) continue; path.push(nums[i]); used[i] true; backtrack(); path.pop(); used[i] false; } }; backtrack(); return result; };8.2 回溯三要素选择将元素加入路径递归继续选择下一个元素撤销回溯到上一步9. 反转链表9.1 迭代法var reverseList function(head) { let prev null; let curr head; while (curr ! null) { const nextTemp curr.next; curr.next prev; prev curr; curr nextTemp; } return prev; };9.2 递归法var reverseList function(head) { if (head null || head.next null) { return head; } const newHead reverseList(head.next); head.next.next head; head.next null; return newHead; };10. 二叉树层序遍历10.1 BFS实现var levelOrder function(root) { if (!root) return []; const result []; const queue [root]; while (queue.length) { const levelSize queue.length; const currentLevel []; for (let i 0; i levelSize; i) { const node queue.shift(); currentLevel.push(node.val); if (node.left) queue.push(node.left); if (node.right) queue.push(node.right); } result.push(currentLevel); } return result; };10.2 关键点队列管理先进先出处理节点层级记录通过levelSize确保按层处理子节点入队左节点先入队11. 最大子数组和11.1 Kadane算法var maxSubArray function(nums) { let currentSum nums[0]; let maxSum nums[0]; for (let i 1; i nums.length; i) { currentSum Math.max(nums[i], currentSum nums[i]); maxSum Math.max(maxSum, currentSum); } return maxSum; };11.2 算法思想当前和为负则抛弃当前和为正则保留始终维护全局最大值12. 三数之和12.1 排序双指针var threeSum function(nums) { const result []; nums.sort((a, b) a - b); const n nums.length; for (let i 0; i n; i) { if (i 0 nums[i] nums[i - 1]) continue; let left i 1; let right n - 1; while (left right) { const sum nums[i] nums[left] nums[right]; if (sum 0) { result.push([nums[i], nums[left], nums[right]]); while (left right nums[left] nums[left 1]) left; while (left right nums[right] nums[right - 1]) right--; left; right--; } else if (sum 0) { left; } else { right--; } } } return result; };12.2 去重技巧排序便于跳过重复元素固定数去重nums[i] nums[i-1]时跳过双指针去重找到解后跳过相同left/right13. 算法学习建议分类练习按算法类型双指针、DFS、DP等集中突破手写实现理解后自己实现不要直接看答案复杂度分析养成分析时间/空间复杂度的习惯反复练习高频题目要多次练习达到熟练在实际面试中面试官不仅考察你能不能解出题目更看重解题思路的清晰度和代码实现的规范性。建议在练习时注意代码风格添加必要注释展现良好的编程习惯。
返回列表