资讯详情

2026算法岗笔试复盘:KMP、回溯剪枝、堆排序与tarjan高频考点全解析

📅 2026/10/10 19:07:27 | 华诺云谱 👁 阅读
2026算法岗笔试复盘:KMP、回溯剪枝、堆排序与tarjan高频考点全解析
上周刚参加完华子2026年3月4日的算法岗笔试趁着记忆还热乎我把整场考试的题型分布、核心题解和踩坑记录整理成一份完整复盘。正在准备算法岗笔试或者面试的同学可以重点关注尤其是一写算法题就容易卡住的这篇会把从暴力枚举到最优解的实现思路都过一遍最后附一份高频考点速查表直接照着复习就行。考完和几个同场的朋友对了一下大家暴露的问题出奇一致KMP的next数组推到一半卡壳八皇后题没想到用剪枝降复杂度堆排序只记住原理却写不出完整代码还有图论题一看是tarjan就直接放弃。说实话这些都不是什么难题纯粹是熟练度不够。算法岗笔试从来不考天赋考的就是你能不能在三十分钟内把模板原样默写出来以及面对陌生题目时能不能快速定位到对应的算法模型。1. 笔试整体复盘时间分配比刷题数量更重要1.1 题型设置与分值构成我拿到的这份卷子是120分钟整体题量大概是4道编程题加10道左右的选择判断题。别看选择题占比不高里面塞了不少机器学习概念题覆盖面包括随机森林、XGBoost、差分隐私、PID控制这类甚至还有一道关于深度强化学习中智能体与奖励信号关系的判断。算法方向候选人如果平时只刷LeetCode不看基础理论这一块很容易被拉开分差。4道编程题集中在几个固定方向上字符串匹配、搜索与剪枝、排序与堆、图论。具体题目风格是这样字符串题主要考察KMP以及暴力枚举的对比优化搜索题是经典的八皇后变体排序题设计成TopK海量数据场景图论题则是有向图强连通分量求法。考点不算偏但每道题都留了优化的空间从暴力解到最优解至少有2到3个层次给分也按照这个梯度来。这就意味着即使不会最优解只要先把暴力枚举版本写出来也能拿到一部分分千万别交白卷。1.2 我的时间分配与答题策略我给自己定的节奏是这样的前10分钟把所有题目扫一遍圈出熟悉的题和完全没思路的题先做最有把握的回溯剪枝题和排序题花40分钟保证AC再花30分钟搞定字符串题KMP忘了可以拿暴力枚举先兜底图论题放到最后用20分钟写tarjan模板并验证写不出来也要把思路和部分代码写上最后20分钟统一检查边界条件、多组输入输出格式和之前跳过的小题。这里最想提醒的一点是不要在第一题上死磕。我当时亲眼看到有人在一道字符串题上卡了四十分钟后面三道题全部来不及写最后连暴力分都没拿全。笔试的目标是总分过线不是单题满分先把确定能拿的分数稳稳攥住再考虑冲难题目。2. 四道核心编程题从暴力枚举到最优解2.1 字符串匹配暴力写法与KMP的考场抉择字符串匹配题给的是经典场景给定文本串T和模式串P要求输出P在T中所有出现位置的起始下标。暴力枚举的思路最简单两层循环外层遍历T的每个位置内层逐个字符和P比对遇到不匹配就break匹配完整就记录起始位置。复杂度是O(n×m)当n和m都是10^5量级时必挂。但它的好处是不容易写错可以作为兜底方案能拿20%到30%的分。KMP算法则能在O(nm)时间内解决。核心思想是利用已经匹配的信息让模式串在匹配失败时不回退到开头而是跳到最长相同前后缀的位置继续匹配。这个最长相同前后缀就是next数组。考场上建议直接背这个版本的实现def get_next(p): m len(p) nxt [0] * m j 0 for i in range(1, m): while j 0 and p[i] ! p[j]: j nxt[j - 1] if p[i] p[j]: j 1 nxt[i] j return nxt def kmp(t, p): nxt get_next(p) res [] j 0 for i in range(len(t)): while j 0 and t[i] ! p[j]: j nxt[j - 1] if t[i] p[j]: j 1 if j len(p): res.append(i - len(p) 1) j nxt[j - 1] return res易错点有三个需要注意next数组的下标起点不同教材写法不一样有从0开始的也有从-1开始的考场不要混着写选定一种就一路用到底匹配成功后要让j nxt[j - 1]不是直接归零否则会漏掉重叠出现的匹配模式串长度为1时构建next数组的循环根本不会执行要单独想清楚逻辑分支。2.2 搜索与剪枝八皇后类回溯题的三个标记数组这道题是N皇后的经典变体要求输出所有合法摆法的数量。八皇后本质是在N×N棋盘上放N个皇后要求任意两个皇后不能在同一行、同一列、同一条对角线上。最差的思路是生成所有N皇后位置的排列再去判断合法性N8的时候勉强能跑N10以上直接爆炸。正解是回溯加剪枝在每一行只尝试当前行所有列位置并用三个布尔数组快速判断当前位置是否冲突。这里最关键的其实是正确的剪枝条件列冲突col[c]为True说明这一列已经放过皇后主对角线冲突行号加列号ij为固定值用diag1[ij]标记副对角线冲突行号减列号i-j可能为负数统一加偏移量n-1用diag2[i-jn-1]标记。参考实现如下def totalNQueens(n): col [False] * n diag1 [False] * (2 * n - 1) diag2 [False] * (2 * n - 1) ans 0 def dfs(row): nonlocal ans if row n: ans 1 return for c in range(n): if col[c] or diag1[row c] or diag2[row - c n - 1]: continue col[c] diag1[row c] diag2[row - c n - 1] True dfs(row 1) col[c] diag1[row c] diag2[row - c n - 1] False dfs(0) return ans这段代码的节奏就是标准的标记—递归—回溯三连。N比较大时还可以用位运算优化用一个整数的二进制位表示可放置位置省掉数组维护和循环判断的常数。但我个人建议考场先用普通回溯版本拿稳分数位运算版本容易写错尤其在紧张状态下很容易把位运算优先级搞混。2.3 排序与堆TopK海量数据三种解法的取舍排序题设计成海量数据的TopK场景给一个长度为n的数组要求找出第K大的数。这题看似简单实则考察的是排序算法选型能力属于典型的一题多解。第一种方法是直接调用排序函数排完后返回下标n-K的元素复杂度O(n log n)。笔试环境完全可以这么写省时省力只要n在百万以内就不会超时。第二种是维护一个大小为K的小顶堆堆顶就是当前第K大的数。每来一个元素如果比堆顶大就弹出堆顶再入堆最终堆顶就是答案。复杂度O(n log K)海量数据且K远小于n时非常适用。第三种是快排的partition思想叫快速选择平均复杂度O(n)可处理更大规模数据。很多考生容易在边界条件上翻车partition返回的是基准元素的最终下标这个下标和K的关系判断必须写对否则递归方向就反了。从备考角度出发我的建议很明确K比较小时用堆n不太大时用排序只有题目明确卡了O(n log n)才会卡分那时才需要上快速选择。笔试别为了炫技选最复杂的写法稳定通过才是硬道理。2.4 图论题tarjan与匈牙利算法的选用判断图论题给了两个方向一道是有向图强连通分量题另一道是二分图最大匹配题。看到强连通分量缩点直接锁定tarjan看到最大匹配最小点覆盖独立集相关关键词则锁定匈牙利算法。tarjan的核心是用一次DFS维护两个数组和一个栈dfn[u]表示u被访问的时间戳low[u]表示u及其子树能够回溯到的最早时间戳每访问一个节点就入栈遍历邻接点v时若v未被访问递归后更新low[u] min(low[u], low[v])若v已访问且在栈中则更新low[u] min(low[u], dfn[v])当dfn[u] low[u]时从栈顶一直弹出直到弹出u这些节点构成一个强连通分量。匈牙利算法的核心则是寻找增广路遍历左侧每个点每次都新建一个访问标记数组再从当前点出发DFS尝试为它寻找右侧可匹配的点。如果右侧点v未被匹配或者v之前的匹配者match[v]能找到新的匹配就更新匹配关系并返回成功。累加成功次数得到最大匹配数复杂度O(V×E)。这两类题目套路性极强属于背模板就能拿分的题强烈建议考前一晚把模板默写两遍确保考场十分钟内写完。3. 考场实战完整代码复盘与踩坑实录3.1 KMP完整实现的闭环复盘我在考场上写的KMP最终版本和上面给的模板几乎一致区别是补了输入输出边界处理。笔试环境和LeetCode不一样不会自动帮你处理空模式串多组输入也要自己循环读这些细节都会在OJ上变成硬性扣分点。我给一个完整可运行的版本测试用例也贴在下面def str_match(t: str, p: str): if not p: return [] n, m len(t), len(p) nxt [0] * m j 0 for i in range(1, m): while j 0 and p[i] ! p[j]: j nxt[j - 1] if p[i] p[j]: j 1 nxt[i] j ans [] j 0 for i in range(n): while j 0 and t[i] ! p[j]: j nxt[j - 1] if t[i] p[j]: j 1 if j m: ans.append(i - m 1) j nxt[j - 1] return ans assert str_match(ababcabcacbab, abc) [2, 5, 9] assert str_match(aaaa, aa) [0, 1, 2] assert str_match(abc, ) [] print(all ok)我这次踩的第一个坑就是没有检查模式串为空导致nxt为空数组后访问nxt[j-1]直接越界报错。这类低级错误在OJ上反馈非常隐晦你不一定能第一时间想到是空输入问题。以后凡是字符串操作第一行永远是判空和边界长度判断。3.2 回溯剪枝顺序写反的深刻教训八皇后那道题我第一次提交时把标记语句写在了递归之后导致同一列放了两个皇后也能进入下一层递归答案数量直接翻倍。这完全不符合逻辑却是在紧张状态下极其容易犯的错误。正确的顺序永远是检查能放后先标记再递归再回溯清标记不允许任何跳步。考场上这种逻辑错误比语法错误更隐蔽因为代码能跑、结果还看起来合理尤其是你事先不知道正确答案数量时很容易蒙混过去。我这道题因为之前刷过剑指offer的原题心里有数所以马上发现答案翻倍了。如果没有原始答案参照建议至少拿N1到N4的小规模用例手算一遍验证逻辑再提交大数据。3.3 笔试环境的其他常见坑位汇总除了上面两道题的具体问题这类大厂在线笔试系统还有几个老生常谈但每年都有人踩的坑。输入输出格式是最常见的坑。有些平台是标准输入输出要求你从stdin读多组测试数据用while循环处理有些平台直接给函数接口你只需要实现函数并返回值。读题时第一件事就是确认到底用哪种模式写错了格式再好的算法也拿不到分。数据类型溢出也值得警惕。涉及累加、乘法、动态规划状态转移时int很可能不够用直接开long long。递归深度大的搜索题如果N超过10^5默认递归栈大概率爆掉要提前考虑显式栈或迭代写法。多组样例的全局变量初始化更是高频失误区。上一组样例跑完留下的全局标记数组没有重置下一组样例结果就会错得莫名其妙。我一般每道题在测试前都会检查一遍是否有全局变量需要清空这个习惯救了我好几次。4. 考点速查表核心算法与概念题复习指南4.1 核心算法分类速查我把这次笔试涉及的算法按类别整理成一张速查表复习时可以直接对照检查掌握情况算法名称核心思想时间复杂度笔试出题形式堆排序用堆结构维护最大/最小值反复调整O(n log n)TopK、排序变体归并排序分治合并需要额外O(n)空间O(n log n)逆序对、链表排序快速排序选取基准partition左右递归平均O(n log n)排序、快速选择冒泡排序相邻两两交换冒泡到正确位置O(n²)概念题、小数据量二分查找有序数组折半搜索O(log n)查找左边界/右边界等暴力枚举遍历所有可能组合逐步验证视条件而定无思路时的兜底方案KMP利用next数组跳过重复前缀匹配O(n m)字符串匹配、子串出现位置tarjan时间戳dfn 回溯值low 栈O(V E)强连通分量、缩点、割点匈牙利算法增广路径法O(V × E)二分图最大匹配、覆盖问题动态规划状态定义 状态转移 初始值根据题目而定序列DP、背包、区间DP回溯剪枝递归搜索 冲突修剪指数级但剪枝后可行八皇后、排列组合、数独并查集路径压缩 按秩合并近O(α(n))连通性、最小生成树辅助这张表里从暴力枚举到KMP、从八皇后回溯剪枝到tarjan和匈牙利算法基本就是此次笔试的核心范围。其中归并排序虽然没有单独出题但结合数组逆序对考察时是标准解建议顺手把归并排序的递归和迭代写法都过一遍。4.2 机器学习与算法概念题的应对方法大厂算法岗笔试的选择判断题很多都是在考察基础理论的广度。我这次遇到的概念题覆盖了机器学习经典模型、隐私保护、强化学习、控制算法等多个方向。这类题不需要推导公式但要求你准确知道某个算法解决什么问题、有哪些关键特性。我把高频出现的方向整理如下随机森林核心是bagging加决策树组合适合处理高维特征抗过拟合能力强XGBoost核心是boosting思想目标函数结合二阶泰勒展开与正则项训练时引入行采样和列采样粒子群优化PSO启发式群体智能搜索算法用来求解连续优化问题差分隐私通过添加噪声来保护个体数据隐私常见机制有拉普拉斯噪声和高斯噪声PID算法比例、积分、微分三种控制律的加权组合属于经典控制理论深度强化学习智能体与环境交互根据奖励信号学习策略代表算法有DQN和PPO语义分割对图像逐像素分类典型网络有FCN、U-Net和DeepLab。记概念题最有效的方式不是死记硬背定义而是抓住这个算法干什么、解决什么问题、有什么优缺点三个角度去串联。比如差分隐私你只要记住它最核心的动作是加噪声一切应用场景都围绕保护个体隐私展开选择题基本不会错。4.3 别被冷门搜索词带偏方向准备期间我也看到不少离谱的搜索热词什么完整性校验算法、3DES双倍长解密算法、twofish算法、HDBSCAN聚类、KCF跟踪参数、slice界面算法与PLIC算法这些。归纳下来它们大多有特定行业背景跟通用算法岗笔试没什么关系。我的建议是除非你投递的岗位JD里明确写了需要某类特殊算法经验否则别把宝贵的时间花在这些偏门词条上。笔试考的是基础算法和数据结构的通用能力是排序、KMP、剪枝、动态规划这些可迁移的硬功夫。等真的进了特定业务组再按需补具体的领域算法完全来得及。5. 备考建议从刷题到拿offer的最后一公里5.1 我亲测有效的三阶段刷题节奏算法岗笔试准备不是冲刺性质的至少需要提前两个月开始滚动复习。我自己的安排是三个固定阶段每个阶段侧重点完全不同基础期控制在2到4周。核心任务是把数组、链表、栈、队列、哈希表、二叉树这六类基础数据结构彻底吃透每天保证2到3道题的量重点是一题多解的底层原理比如同一个数组题分别用暴力枚举、哈希、双指针各写一遍感受不同解法的复杂度差异。专题期控制在3到6周。这个阶段按算法专题刷题排序专题、二分专题、DFS/BFS专题、回溯剪枝专题、动态规划专题、图论专题依次推进。每个专题先背模板再刷变体题比如回溯模板搞清楚标记—递归—回溯流程后再去刷八皇后、组合总和、全排列等变体效率和记忆深度都会高很多。冲刺期是考前的最后两周。这个阶段不再刷新题而是反复做目标公司历年笔试真题和面试高频题严格模拟真实考试时间到点交卷错了的题整理成错题集反复看。LeetCode的必刷基础题和剑指offer的全题是这时候最好的支撑材料。5.2 考场上最实用的三个即时技巧刷题之外考场上的临场发挥也占很大比重。提前把常用算法模板背到肌肉记忆级别。KMP、tarjan、并查集、快排partition、滑动窗口、二分边界处理这些都是高频模板考场上直接默写能省下大量排查时间。背模板不是死记硬背而是理解每一步的作用后能够快速复现并做小范围改动。准备一张一页纸的边界检查清单。考完一道题提交前花30秒快速确认这几个点数组长度是否为0或1是否需要long long多组测试数据是否初始化了全局变量输出格式是否与题目要求一致我在实际考试中靠这个清单至少避免了三次低级扣分。卡壳超过15分钟果断跳题。这个策略不是放弃而是给大脑留出酝酿时间。很多题当时想不通做完下一题再回头思路突然就通了。我在图论题上卡了十几分钟后转战排序题回头再写tarjan模板时顺了很多。5.3 笔试当天的一个实用建议考前一晚不要刷难题了把这次整理的考点速查表从头到尾过一遍确认每个算法的应用场景和复杂度都心里有数然后早点睡。笔试当天带一张草稿纸先把默写模板和复杂度清单写上做题时遇到熟悉的直接对照抄遇到陌生的先标记跳过。这种先写后查的方式能极大减少考场的紧张感。另外我习惯把每道题按暴力解→优化→最优解三层拆解哪怕最优解写不出来也要先把暴力枚举版本完成提交。在笔试评分体系下暴力解往往能拿到三成左右的分这三分可能比最后一问最优解的两分更好拿。别小看这类保底分最终过没过线往往就差在这里。这场2026年3月4日的华子算法岗笔试给我最大的感受是侥幸心理是最致命的。KMP和tarjan看着复杂只要考前老老实实默写几遍考场就是送分题反而是那些觉得大概会就略过的算法现场一紧张根本写不出来。如果你也在准备算法岗笔试我强烈建议把所有高频模板练到30分钟内完整默写的程度再考虑那些偏题怪题。基本功扎实了笔试就只是走个流程。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑