ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

美团算法策略笔试复盘:从KMP到图论的考点全拆解

美团算法策略笔试复盘:从KMP到图论的考点全拆解 先说结论美团算法策略端的笔试是我今年秋招参加过的几场笔试里风格最“分裂”的一场。上午的选择题还在考你KMP的next数组怎么求下午的编程题直接甩给你一道需要建模加调参的启发式搜索题。这种“基础策略”双轨并行的考察方式恰恰是算法策略岗区别于纯后端开发岗的核心信号——他们要的不是只会写业务CRUD的人而是能把算法落地到真实业务场景里、用策略思维解决问题的候选人。我参加的是2025年秋招第一批笔试整体感受是题量不小、覆盖面广、难度梯度明显。如果你正在准备美团或者其他大厂的算法策略岗这篇内容值得你花十分钟看完。我会从试卷结构、高频考点、真题思路复盘、避坑指南四个维度彻底拆解尽量还原我当时在考场上的真实反应和决策过程。1. 笔试整体结构与考察思路拆解1.1 试卷结构题型分布与分值占比美团算法策略端的笔试和纯研发岗的笔试有一个明显的区别不只是考代码还考算法原理、机器学习基础、甚至一些偏工程实现的策略问题。我那一场的题型分布大致是题型数量分值占比考察方向单选题15题20%数据结构、算法原理、机器学习基础多选题5题10%策略设计、模型评估、算法适用场景编程题3题45%数据结构与算法实现、优化策略简答/设计题2题25%业务场景中的算法策略方案设计这个分值结构很有意思。编程题只占了不到一半的分剩下大头给了选择题和设计题。很多人拿到卷子就开始闷头刷编程题结果选择题里栽了跟头。事实上选择题和设计题恰恰是拉开差距的地方——因为这些题目没有标准答案模板靠的是平时积累的算法直觉和业务理解。我记得很清楚单选题里有一道考KMP算法next数组的题模式串是abacaba要你写出对应的next数组值。这道题刷过LeetCode的人基本都能做但如果只是死记硬背求next的代码不理解前缀后缀匹配的原理很容易在边界条件上出错。后面我会专门讲这道题。1.2 题目背后的岗位能力映射为什么美团算法策略端要考这么多基础算法不是说策略岗就只需要会调包调参而是因为算法策略端的日常工作本质上是“用算法解决业务问题”——推荐系统、搜索排序、物流调度、定价策略哪个场景离得开基础算法先说搜索排序。排序算法不是只在教科书里出现你在美团外卖里搜“黄焖鸡米饭”背后的商家排序用到的就是堆排序思想维护一个TopK的候选集。再说物流调度。外卖骑手的路径规划本质上是图论问题Dijkstra算法和A*搜索是基础中的基础。再比如语音交互场景里的音频处理音频重采样算法、卡尔曼滤波这些都在选择题里出现。所以美团算法策略端的笔试本质上是在筛选两类能力一类是算法基本功扎实看得懂代码、写得出实现另一类是策略思维清晰面对一个开放性的业务问题能拆解成算法问题并给出合理方案。编程题考基本功简答/设计题考策略思维选择题则两者兼顾。2. 高频算法知识点详解考场上哪些考点反复出现2.1 字符串与模式匹配KMP算法的next数组细节KMP算法几乎是美团笔试选择题的常客。这里不展开讲完整原理只讲一个我踩过坑的细节next数组的定义方式。不同的教材对next数组有两种不同的定义——一种是以当前字符前的最大匹配长度为next值另一种是以下标从0开始的失配跳转位置。美团这道题明确写了“next[i]定义为模式串中前i个字符构成的子串的最长相等前后缀长度”这个定义下模式串abacaba的next数组是i子串最长相等前后缀长度next[i]0a001ab002aba1a13abac004abaca1a15abacab2ab26abacaba3aba3答案是0 0 1 0 1 2 3。如果我对next数组的定义理解得不够清楚把next[i]当成“失配时跳转到的位置”来算就会得到完全不同的结果。所以备考时一定要先跟题目对齐定义不要默认自己熟悉的版本。2.2 排序与TopK问题堆排序的实际应用场景选择题里有一道“在n个元素中找到最大的k个数”的题选项涉及冒泡排序、快速排序、堆排序和桶排序。题目本身不难但它考察的是你对各排序算法时间复杂度和适用场景的理解。冒泡排序O(n²)直接排除快速排序虽然平均O(nlogn)但最坏情况下是O(n²)用于TopK问题不够稳定。正确的思路是维护一个大小为k的最小堆堆顶是当前k个最大元素中的最小值遍历一次数据每次和堆顶比较大于堆顶就替换并堆化最终得到TopK。时间复杂度是O(nlogk)空间复杂度O(k)。这个思路在美团的实际业务场景中非常常见。比方说美团App首页的商家推荐候选集可能有几十万个商户但最终只需要展示二十个这时候就需要用TopK算法快速筛选。不一定是堆排序但思想是相通的。2.3 图论与路径规划Dijkstra、二分图HK算法、剪枝编程题的第二题考了一道图论题我当时第一反应是Dijkstra但题目模型稍微做了一点变形——每条边不仅有权重还有一个状态属性当处在某种状态下时经过某些边需要额外代价。这种“状态相关的图论问题”需要把状态维度拆进节点里本质上就是拆点建图。拆点建图这个技巧很多人刷题时遇到过但不一定能想到。它的核心思想是如果某个节点在不同状态下有不同的行为就把这个节点拆成多个节点每个节点代表一种状态然后在新图上跑最短路。我当时看到题目里“状态”那两个字立刻意识到要用拆点建图因为这是一个非常典型的套路。如果你在考场上遇到不会做的图论题第一优先考虑的就是拆点、分层图、虚拟节点这三个技巧。另外我在简答题里还看到了类似“外卖配送路径规划中如何减少搜索空间”的问题这其实就是在考剪枝策略。剪枝算法在搜索问题里是核心优化手段。比如A*搜索里的启发式函数曼哈顿距离、欧几里得距离的选择直接决定了剪枝效率。2.4 启发式算法与优化粒子群、模拟退火选择题的最后几题出现了粒子群算法和模拟退火算法。说实话这两道题考得非常细不是那种“你知道有这个东西就能做对”的题而是真的考察你对算法原理和迭代过程的理解。粒子群算法PSO的核心是每个粒子有位置和速度两个属性每次迭代更新时需要综合考虑三个因素粒子自身的历史最优位置pbest、整个群体的全局最优位置gbest、以及粒子当前的运动速度。更新公式里的惯性权重w、个体学习因子c1、社会学习因子c2这些参数的取值范围和含义选择题里真的有考到。模拟退火算法则考察了Metropolis准则——在温度T下如果新解比当前解好就无条件接受如果新解比当前解差以概率exp(-ΔE/T)接受。理解这个概率公式比背下来更重要因为笔试可能不会让你写这个公式但会让你判断“当前温度T10ΔE5时接受较差解的概率是多少”这类问题。这类启发式算法虽然很少直接出现在编程题里但在策略设计题中经常会出现。比如简答题让你设计一个外卖骑手调度策略你提到用粒子群算法优化路径面试官会追问你参数怎么设、收敛条件怎么判断这都是在考察你对算法原理的深度理解。3. 机器学习与策略设计笔试中那些“算法策略”的考察重点3.1 机器学习基础聚类、KNN、强化学习美团算法策略端的笔试有一个特点机器学习基础题覆盖很广但难度适中。考察内容主要集中在五大块传统机器学习SVM、决策树、KNN、聚类算法、深度学习CNN、RNN、Transformer的基础概念、强化学习基本框架和概念、模型评估过拟合、交叉验证、评价指标、特征工程归一化、离散化、缺失值处理。聚类算法几乎是必考内容。K-Means、DBSCAN、层次聚类各自的优缺点和适用场景要能说清楚。K-Means这题我印象很深因为问的是“当数据中存在离群点时K-Means聚类结果会受到什么影响”正确答案是“聚类中心会被离群点拉偏导致聚类结果不稳定”。如果你只是知道K-Means的步骤初始化中心点、分配样本、重新计算中心、迭代不理解目标函数是最小化平方误差很难判断离群点的影响。K-Means用均值更新中心点均值对离群点敏感所以聚类中心会被拉偏。这不是死记硬背而是需要对算法本质有理解。KNN的分类能力也出现在多选题里。题目问KNN算法能用在哪些方面选项有分类、回归、密度估计、异常检测。很多人只知道KNN能分类实际上KNN做回归用最近的k个样本的均值作为预测值也是常见的用法。密度估计和异常检测也都能用KNN实现当待测样本到最近邻的距离明显大于其他样本时基本可以判定为异常点。强化学习考得比较基础问MDP马尔可夫决策过程由哪些要素组成——状态、动作、奖励、转移概率、折扣因子。再就是Q-Learning的更新公式。这些属于入门级知识点不需要你深入理解深度强化学习但基本概念必须要熟悉。3.2 图像与信号处理算法Sobel、拉普拉斯、卡尔曼滤波、音频重采样图像算法和信号处理算法在算法策略端笔试里也会出现这可能是很多人没有预料到的。我那一场选择题里出现了Sobel算子、拉普拉斯算子、卡尔曼滤波、音频重采样、图像锐化、图像分类算法等大量和视觉、语音相关的考点。Sobel算子考的是它在图像边缘检测中的作用——Sobel算子通过计算图像灰度在水平和垂直方向的一阶导数来检测边缘结合了高斯平滑和差分。拉普拉斯算子则是二阶导数算子对噪声敏感。题目如果问“图像锐化用哪种算子”答案就是拉普拉斯算子。因为拉普拉斯算子的输出是二阶导数在边缘处响应最强把原始图像和拉普拉斯结果叠加可以让边缘更突出也就是锐化效果。卡尔曼滤波出现在一道关于“目标跟踪”的题目里。卡尔曼滤波的核心是预测和更新的迭代过程先用状态转移方程预测下一时刻的状态再用观测值更新预测值最后得到最优估计。它在导航、目标跟踪、信号处理领域有着极其广泛的应用。美团做无人机配送、无人车配送卡尔曼滤波是传感器融合的基础算法所以考这个点并不意外。音频重采样算法出现在一道场景题里——语音助手采集到的音频采样率是16kHz但识别模型要求8kHz的输入需要做什么处理。这考的是重采样。重采样的核心是插值算法上采样需要插值下采样需要抽取但直接抽取会引入混叠效应所以要先经过低通滤波器。笔试不会考你实现细节但会考你“为什么下采样前需要低通滤波”——记住这个关键点就够了。3.3 经典工业控制算法PID与MPPT、FOC看到PID算法出现在美团笔试的选择题里我当时是有点意外的。题目大意是“PID控制器的三个参数Kp、Ki、Kd分别起什么作用”。这不难Kp是比例系数加快响应速度但过大会导致超调Ki是积分系数消除稳态误差但过大会导致振荡Kd是微分系数抑制超调、改善系统稳定性但对噪声敏感。为什么美团会考PID我猜测和无人机、自动配送车这类物理硬件系统的控制有关。算法策略端不完全是纯软件还涉及和硬件系统的交互。你不需要精通PID调参但至少要明白反馈控制系统的核心逻辑——让系统输出跟踪目标值通过误差反馈来调整控制量。FOC磁场定向控制这个考点也出现了但考得比较浅只是问“FOC算法在电机控制中主要用于什么”——答案是“通过坐标变换实现解耦控制”。这种题你不会做也不用慌它属于交叉领域知识考的是知识面广度。但如果你正好了解过就能在选择题里多拿一分。我的建议是备考时把这类“边缘考点”过一眼混个脸熟不要花太大力气。3.4 数据检索与排序BM25算法让我意外的是有一道多选题考了BM25算法。这道题的问题是“BM25算法中影响文档得分的因素有哪些”选项包括词频TF、逆文档频率IDF、文档长度、词项在文档中的位置。正确答案是词频、逆文档频率和文档长度。词项位置不影响BM25得分——虽然影响人阅读时的感知权重但BM25公式里没有位置这个因子。BM25是搜索引擎里最经典的相关性排序算法之一用于计算查询词和文档之间的相关度。它是在TF-IDF的基础上做了改进引入文档长度归一化用avgdl做平均长度归一化引入饱和度和非线性词频惩罚。美团搜索场景、商家检索场景都会用到BM25所以考它非常正常。如果你在做搜索、推荐、广告相关的算法岗位BM25几乎是必问的知识点。4. 实战复盘三道编程题的完整思路与代码实现4.1 编程题第一题TopK问题的变体题目大概是这样的给定一个整数数组和一个整数k要求找出数组中第k大的元素。LeetCode 215原题很简单。但笔试平台的输入输出读入方式和LeetCode不一样需要自己处理。我当时用快排分区思想quickselect实现的时间复杂度平均O(n)最坏O(n²)。def find_kth_largest(nums, k): k len(nums) - k # 第k大转化第(len-k)小 def quick_select(left, right): pivot nums[right] store left for i in range(left, right): if nums[i] pivot: nums[store], nums[i] nums[i], nums[store] store 1 nums[store], nums[right] nums[right], nums[store] if store k: return nums[store] elif store k: return quick_select(store 1, right) else: return quick_select(left, store - 1) return quick_select(0, len(nums) - 1)如果你不想写快排分区用堆排序也可以。维护一个大小为k的最小堆遍历数组动态更新堆内的k个最大值最后堆顶就是第k大。时间复杂度O(nlogk)在k较小的时候效率更高。笔试直接写堆排序版本更稳妥不容易边界出错而且代码逻辑更直观。这道题我是用归并排序的思路先排序再直接取下标——当时可能紧张了直接调了内置sorted函数虽然能通过但明显不是一个算法岗候选人该有的表现。这是我这场笔试的一个教训平时刷题用惯了LeetCode自带的输入输出到笔试平台反而容易露怯。建议你备考时一定要多练笔试平台的代码环境适应手动处理输入输出的方式。4.2 编程题第二题状态图最短路径拆点建图这道题比较复杂题目背景是“外卖骑手送餐过程中在不同天气状态下骑行不同路段的耗时有差异求最短耗时”。比赛骑手的状态包括“晴天”和“雨天”两种某些路段在雨天会增加额外的时间。输入是图结构、边的权重、天气状态切换的代价。我当时的思路就是前面提到的拆点建图。把每个节点拆成两个节点节点x_0表示“晴天到达节点x”节点x_1表示“雨天到达节点x”边的权重要根据源节点和汇节点的状态来确定。如果骑手从晴天节点x_0走到晴天节点y_0需要的耗时是正常耗时如果从雨天节点x_1走到雨天节点y_1耗时是雨天耗时如果从晴天节点x_0走到雨天节点x_1代价是切换到雨天的代价从雨天切回晴天同理。拆点完成后在2N个节点的新图上跑Dijkstra即可。关键是代码里的状态转移逻辑要写对。以下是我的实现思路Python伪代码import heapq def min_time(n, edges, weather_switch_cost, start, end): # 构建邻接表节点编号 0..n-1 graph [[] for _ in range(n)] for u, v, w_sunny, w_rainy in edges: graph[u].append((v, w_sunny, w_rainy)) graph[v].append((u, w_sunny, w_rainy)) # dist[i][state] 表示到达节点i并且处于state状态0晴1雨的最短时间 dist [[float(inf)] * 2 for _ in range(n)] dist[start][0] 0 pq [(0, start, 0)] # (time, node, state) while pq: time, node, state heapq.heappop(pq) if time dist[node][state]: continue # 切换天气状态原地切换 new_state 1 - state new_time time weather_switch_cost if new_time dist[node][new_state]: dist[node][new_state] new_time heapq.heappush(pq, (new_time, node, new_state)) for v, w_sunny, w_rainy in graph[node]: w w_sunny if state 0 else w_rainy new_time time w if new_time dist[v][state]: dist[v][state] new_time heapq.heappush(pq, (new_time, v, state)) return min(dist[end])这道题的坑点在于状态可能在同一条路径上需要多次切换。我的解法允许在任何节点原地切换天气状态代价是weather_switch_cost同时在不同状态下走同一条边会得到不同的权重。这样处理之后拆点建图的标准解法直接套Dijkstra就能解决。但我复查时发现我最初的写法里漏掉了一个关键细节我没把天气切换动作放在遍历边的逻辑之前导致有的先切状态再走的方案没有考虑到切换后的状态。后来修正为“在每个节点先尝试切换状态再尝试走向邻居”。这种细节写代码时很容易漏一定要在思路上先搭好框架再动手。4.3 编程题第三题区间调度与贪心策略第三题是典型的贪心算法题题目类似“会议室预订”——给定若干个区间求最多能选多少个互不重叠的区间。经典的区间调度问题按结束时间排序每次选最早结束的区间然后跳过所有和它重叠的区间。这题如果刷过LeetCode的“无重叠区间”435题和“用最少数量的箭引爆气球”452题基本就是降维打击。核心思想是局部最优选择最早结束的区间就是全局最优解。这里的关键是为什么不能按开始时间排序举个反例就明白了区间[1, 100]开始时间很早但它几乎覆盖所有其他区间按开始时间排序就会得到错误答案按结束时间排序选[1, 2]、[3, 4]显然更优。这道题难度不大但我当时花了将近二十分钟在第二题上导致第三题没时间仔细检查。考场上遇到这种情况我的建议是先把所有题的第一眼能写出的暴力解法或者贪心解法先写上拿到基础分再回头优化。不要在一道难题上耗太久编程题只要思路对、代码能跑哪怕不是最优解也能拿到部分分数。5. 高频算法与知识点的联系从笔试看岗位技术栈5.1 为什么美团算法策略端考这么多不同的算法簇美团业务线非常庞杂外卖、到店、酒旅、出行、优选、买菜、快驴、无人配送……每个业务都有自己独特的算法需求。搜索排序需要排序算法、BM25、LTRLearning to Rank模型推荐系统需要协同过滤、Embedding、双塔模型物流调度需要图论算法、路径优化、车辆路径问题VRP求解语音交互需要音频重采样、语音识别、信号滤波无人配送需要卡尔曼滤波、PID控制、路径规划、避障算法。所以笔试覆盖面广不是故意刁难你而是美团算法策略端的技术栈本身就宽。它不像互联网公司的纯后端开发岗那样只考数据结构和算法它还要求你对机器学习算法、深度学习算法、甚至信号处理、控制理论都有所了解。这个现象背后反映的是“算法策略”这个岗位的本质——它不是一个纯粹的软件工程岗位而是一个“算法业务”的复合型岗位。5.2 从笔试考点看算法策略端的日常技术栈选择题里出现的知识点几乎都能在美团实际业务中找到对应场景。笔试考点业务场景排序算法、TopK商家候选集排序、排行榜KMP、字符串匹配搜索词纠错、敏感词过滤、菜单匹配Dijkstra、图论、剪枝外卖配送路径规划、骑手调度BM25商家搜索相关性排序聚类算法用户分群、商家分层、异常检测卡尔曼滤波、PID无人配送车/无人机状态估计与轨迹控制音频重采样语音交互、音频处理启发式算法粒子群、模拟退火组合优化问题、调度策略求解强化学习智能定价、广告投放、推荐策略这一点非常重要备考时不要只刷LeetCode要主动去了解这些算法在工业界是怎么用的。比如我上面提到BM25和排序关系密切那你还应该知道美团搜索的整体流程——从查询理解、召回、粗排到精排、重排每个环节都用到了什么算法。笔试不直接考但简答题和面试深度挂钩。5.3 算法策略岗和普通后端算法工程师的区别很多人分不清“算法策略”和“普通后端/客户端里的算法”的区别这直接影响备考策略。算法策略端更强调“策略”两个字——你需要从业务数据中发现问题、设计算法策略、评估效果、迭代优化。所以笔试里会有简答题问“如何设计一个策略来提升外卖商家的出餐效率”这种题目没有标准答案考察的是你的分析框架和策略设计能力。而普通的后端算法工程师更强调“实现”——给你一个明确的算法需求你把它高效稳定地实现出来即可。理解了这一点你就能理解为什么美团笔试里既有纯算法题又有策略设计题。前者考察你的“算法实现”能力后者考察你的“算法思维”能力。两种能力缺一不可。6. 常见问题与避坑指南笔试现场的那些“坑”和“招”6.1 时间分配不合理最容易犯的错误我这场笔试总时长120分钟选择题占比35%编程题45%简答题20%。我一开始在选择题上花了太多时间尤其是那道KMP的next数组我反复算了好几遍花了将近十分钟严重挤压了后面编程题的时间。正确的策略应该是先花两分钟快速浏览整张卷子对题量、难度有个整体判断。如果选择题太纠结先标记跳过优先保证编程题有足够时间。编程题的分值更高而且部分用例通过也有分性价比远高于一道死活算不出来的选择题。6.2 编程题输入输出处理不当笔试平台和LeetCode不一样需要自己处理输入输出。笔试平台上的输入可能有多行而且类型混在一起读数据的时候很容易出错。我当时第一题因为用了input().strip().split()之后没转成int直接报了类型错误浪费了两分钟。这里分享一个笔试通用的输入模板import sys def solve(): data sys.stdin.read().strip().split() # 根据题目要求依次取出 n int(data[0]); k int(data[1]) arr list(map(int, data[2:2n])) if __name__ __main__: solve()用sys.stdin.read()一次性读入全部数据再统一处理比一行一行input()要稳定得多尤其是当数据行数不确定的时候。6.3 忽略边界条件和极端用例编程题里最常见的失分点就是边界条件没处理。比如第一题找第k大的数当k1或kn时快排分区的左右边界会指向同一个位置需要额外判断。如果写递归版本的quickselect务必保证递归终止条件包含left right的情况。再比如区间调度题如果区间列表为空或者所有区间长度为零都要能正常处理。我建议在写完代码后花三十秒检查这三个边界空输入、单元素输入、最大规模输入。这三类用例能用最少的精力帮你避免最多的失分。6.4 简答/设计题的答题策略别写散文写方案简答题是算法策略端笔试的重头戏分值20%以上。这类题目没有标准答案但评分标准通常看重三点逻辑是否清晰、方案是否可行、是否有深度。我个人的答题模板是——“问题定义-核心难点-方案设计-实验评估”四步走。简单说就是先明确你要解决什么问题再说清楚难点在哪里然后给出你设计的解决方案包括细节最后说明怎么验证方案的有效性。举个例子简答题如果问“如何设计一个策略来预测外卖配送时长”我的回答可能这样组织先定义问题——预测从商家出餐到骑手送达用户手中的时间。然后分析难点——出餐时间不确定性、骑手路径变化、天气影响、高峰期拥堵。再给出方案——基于历史订单的数据统计利用梯度提升树模型融合多维度特征商家历史出餐时长、骑手历史配送时长、当前天气、时间段、距离等。最后是评估——用MAE或MAPE作为预测误差指标对比基线模型历史平均值的提升百分比。这种结构化的回答方式即便没有很深的优化细节阅卷人一眼看过去也知道你具备完整的策略设计思维。这比洋洋洒洒写一大堆“我认为应该用机器学习”之类的空话要有效得多。6.5 考前一晚和考试当天的具体建议最后说点实用心得。考前一晚不建议再刷难题、偏题把常考的排序算法、KMP、Dijkstra、聚类、PID这些基础概念过一遍保持状态即可。考试当天建议提前30分钟测试笔试环境确认编译器能正常使用然后调试一下输入输出模板。美团笔试平台支持Python、Java、C等主流语言我推荐用Python写题速度最快——特别是涉及到字符串处理、字典操作、堆排序这类场景时Python的标准库能省不少时间。但要注意Python在大数据量下可能超时比如亿级数据的排序或图遍历建议如果题目明确说数据量在百万级别以上优先用C或者Java。今年秋招我的感受是大厂笔试越来越卷题目难度在提升覆盖面在扩大。尤其是算法策略端它考的已经不只是“算法”本身而是“你在真实业务中的算法决策能力”。所以你备考时除了刷LeetCode还要养成一个习惯看到任何算法先问自己一句“这个算法在真实产品里能解决什么问题”。一旦建立了这个思维你不仅笔试能拿高分后面的面试也会顺畅很多。另外最近几场笔试我发现多目标优化、启发式搜索这类软计算题出现的频率在增加。建议把粒子群算法的参数调节、模拟退火的温度衰减、遗传算法的编码交叉选择这些关键细节都过一遍选择题很爱考细节。还有BM25这种检索算法很多刷题网站都不覆盖但美团笔试真考了建议专门去了解一下它的公式和影响因素。最后再分享一个小技巧笔试结束前如果编程题时间充足一定要自己构造几个测试用例验证代码。用一个简单到一眼就能算出结果的用例、一个中间规模用例、一个最大规模用例分别能验证逻辑正确性和性能。这十几分钟的检查往往能让你多拿一个用例的分直接拉开排名。
返回列表