1. 第2场笔试给我的整体印象:时间紧、样例弱、边界多
1.1 试卷结构与时长带来的压迫感
我参加的是美团2023校招技术岗的第2场在线笔试,整场下来最大的感受就是:题量不算夸张,但时间分配稍有不慎就会翻车。编程题部分通常是4道,考试总时长在100分钟上下,意味着平均每道题只有25分钟。这个时间不是让你慢慢推公式的,而是要求看到题目后几分钟内就要确定算法方向,然后直接撸代码。如果你在笔试前没有大量训练“快速识别考点”的能力,大概率会在第三题或第四题卡住,最后只能眼睁睁看着时间走完。
美团笔试的题目描述通常很精简,不会像LeetCode那样把背景讲得很完整。它更像是在模拟真实业务里那种“给你一段含糊的需求,自己补全所有条件”的状态。第2场给我的感觉尤其如此:样例给得非常弱,经常是几组简单的边界数据,跑通了样例不代表能AC,因为隐藏用例几乎全在边界上。比如数组长度为1、数据范围顶到10^9、字符串全是相同字符,这些情况在样例里都看不出来,但后台一定会测。
1.2 难度梯度与“放弃战术”的实际作用
第2场笔试的难度梯度我认为是“1基础、2中等、3中等偏上、4压轴”。前两道题属于常规练习量足够就能解出的水平,第三道开始涉及更复杂的建模,第四道通常是贪心套动态规划或者数据结构优化,很多人连题目都要读两遍。我当时的策略是:先花3分钟快速浏览全部4道题,给每道题按“预计难度”和“是否有思路”打标签,然后把前两题做扎实,第三题如果15分钟没有完整思路就先跳过,最后再回头啃。
这种“放弃战术”听起来不体面,但在限时编程里非常实用。你首先要保证的是“能拿的分一分不丢”,而不是“压轴题死磕到底”。我认识好几个一起笔试的同学,就是因为在第二题上追求最优解,反复优化,结果第四题连暴力分都没来得及写。美团这类公司的笔试通常不公布每题分值,但从面试邀约情况看,前两题全过、后两题部分过,同样能进入下一轮。所以我的建议是:除非你是冲着满分去的,否则优先保证前两题AC,后面两题拿部分分。
2. 从第2场反推的高频考点:贪心排序、动态规划、图论建模
2.1 贪心和排序为什么是重头戏
美团第2场笔试里,贪心算法出现的频率非常高,而且不是简单的那种“每次取最大”的题,而是需要你先排序、再证明选择策略的经典套路。最典型的是区间类问题:给你若干任务区间,要求选择最多不重叠的任务,或者覆盖某个目标区间的最少区间数量。这类题的核心是先按区间右端点或左端点排序,再通过局部最优推导全局最优。很多同学看到区间就想到线段树,其实大多数情况下贪心就够了。
我印象中有一道题是给了一组“开始时间、结束时间、收益”的任务,要求选择若干互不重叠的任务使总收益最大。这个题直接贪心是不行的,因为收益权重会打破“早结束优先”的策略。当时我一眼就看出这是一个“加权区间调度”问题,需要先按结束时间排序,再用动态规划配合二分查找来做。这个混合考法很聪明:表面上是贪心区间,实际考的是“排序预处理 + DP状态转移”的组合能力。如果你只会背模板,不理解排序是为了让问题变成有序递推,遇到这种题就会懵。
2.2 动态规划的常见包装:环形、二维网格、状态机
动态规划是第2场笔试逃不开的考点。但它不会直接告诉你“这题用DP”,而是会把DP包装成各种业务场景。比如环形数组最大子段和、二维网格从左上角到右下角的最短路径、买卖股票系列的状态机版本。我赛后和同场考生交流,普遍认为第2场的DP题比第1场更“绕”,因为题目描述里混入了大量无关信息,比如“商家优惠券叠加”“骑手配送路径”,你需要先剥离业务外壳,才能看出底层是经典模型。
以环形数组最大子段和为例,熟悉套路的人都知道要分两种情况讨论:最大子段不跨环,那直接做一次线性DP;最大子段跨环,等价于数组总和减去最小子段和。这个思路本身不难,但美团会把它包装成“在环形餐桌上安排服务人员,要求连续一段人数最多,但所有人不能同时休息”之类的场景。如果你没有在刷题阶段建立“环形数组”的映射,考场上很容易被题干带偏。所以我一直强调:刷题不要只刷题号,要把每道题的“抽象模型”记下来,形成条件反射。
2.3 图论和搜索的隐蔽考法
第2场的图论题不是让你写裸的Dijkstra或Floyd,而是把图论藏在“依赖关系”里。比如有一类题是任务调度:若干任务之间存在先后依赖,每个任务有执行时间,问按拓扑序执行完全部任务的最短时间。这种题目一眼看过去像是模拟,但本质是“拓扑排序 + 动态规划求最长路径”。你需要先建图,统计入度,用队列做拓扑遍历,同时维护每个节点的最早开始时间。注意,最短完成时间不是求“路径和最小”,而是求“关键路径最长”,因为所有依赖链都必须完成,总时间取决于最长的一条链。
还有一道题考察了DFS剪枝,当时很多人在“是否使用记忆化搜索”上犹豫。那道题的数量级大约是n=20左右,直接暴搜会超时,但加上状态压缩就能过。这种题最坑的地方在于,25分钟的限制下你很难有时间去写复杂的剪枝,所以最好的办法是在平时就练熟“状态压缩DP”和“记忆化搜索”的转换。看到n很小(比如不到20)就条件反射地想到状态枚举,看到n较大但每个状态转移有限,就想到记忆化。这是第2场笔试给我最深刻的教训之一。
3. 四道编程题的复盘式思路演示(非原题,等价模型)
3.1 区间合并类:先排序,再讨论重叠
第一类高频题是区间合并的变体。假设输入给你若干“时间段”,每个时间段有开始时间和结束时间,你要把重叠的时间段合并,并输出合并后最长的连续空闲时间。核心做法分两步:
- 把所有区间按左端点从小到大排序;如果左端点相同,按右端点从小到大排序。
- 维护当前合并区间的左右端点。遍历每个区间,如果新区间的左端点小于等于当前右端点+1,就扩展右端点;否则结束当前区间,开启一个新的合并区间。
这个算法的复杂度是O(n log n),瓶颈在排序。我当时用了C++的sort,自己写了比较函数,注意了long long的使用,因为时间点可能给到10^9量级。很多人在这个题上翻车是因为没有处理“区间左端点相同,右端点乱序”的情况,导致合并结果错误。其实你只要记住:排序之后,当前区间的右端点一定不会比之前的更靠前,这样合并就是线性扫描,非常稳。
3.2 环形数组最大子段和:分情况讨论
第二类题是环形数组最大子段和。给你一个环形整数数组,允许从任意位置开始连续取一段,问最大和是多少。如果数组是线性的,大家都会用Kadane算法:维护当前累加和,如果累加和小于0就重置为0,同时记录历史最大值。但环形意味着子段可以“跨过”数组首尾相接。
等价解法是:最大环形子段和 = max(线性最大子段和, 数组总和 - 线性最小子段和)。
这个公式成立的原因在于,如果子段跨越了首尾,那么数组剩余部分一定是不跨越首尾的连续子段,且它的和是最小的。所以问题转化为同时求最大子段和与最小子段和。我当时的实现是写一个函数,传入一个“取反”标志,用同样的DP逻辑分别求最大和最小。要注意的是,如果数组全是负数,环形最大子段和其实等于最大的那个负数,但按公式“总和 - 最小子段和”可能得到0,必须特判这种情况。这个边界是隐藏用例的常客。
3.3 任务调度与关键路径:拓扑排序求最长路
第三类题是任务调度。有N个任务,编号1到N,每个任务有一个执行时间,另外给定M条依赖关系,表示任务A必须等先前的某个任务完成之后才能开始。问完成所有任务的最短时间。这类题的标准解法是:
- 根据依赖关系构建邻接表,同时记录每个节点的入度。
- 初始化一个队列,所有入度为0的任务可以立刻开始,记录该任务的完成时间。
- 弹出队首任务u,遍历所有u的后继任务v,将v的入度减1。当v的入度变为0,更新v的完成时间为“v的执行时间 + max(所有前置任务的完成时间)”,然后把v入队。
- 最终答案就是所有任务完成时间的最大值。
这里最关键的思维转换是:最短总工期不是所有路径的最小值,而是依赖图中最长路径的值。你可以类比为做饭:煮饭要30分钟,炒菜要10分钟,但炒菜需要等饭煮好,总时间就是30分钟而不是40分钟。第2场笔试里的任务调度题还把执行时间分成了“准备时间”和“执行时间”,本质上还是同一套拓扑结构,只是节点权值计算更复杂。
3.4 状态压缩计数:小数据量下的搜索优化
第四类压轴题往往和状态压缩有关。例如给你一份菜单,每种食材有一个价格,要求选择若干食材,使得总价格刚好等于一个目标值,且每种食材只能选一次,问有多少种选择方案。乍一看是01背包,但数据范围很小(比如n=20,目标值也不大),用动态规划也能解。但美团的出题风格常常把“目标值”改得很大,10^18这种,普通DP开不了数组,只能走搜索+剪枝。
这时“双向搜索”(meet in the middle)就是一个非常优雅的策略:把20个食材分成前后两组,每组10个;分别枚举两组所有可能的组合价格,存到两个列表里;然后排序其中一个列表,遍历另一个列表,用二分查找找互补价格的数量。这样时间复杂度从O(2^20)变成O(2^10 * log(2^10)),完全可行。这种思路在LeetCode上不算高频,但在校招笔试的压轴题里越来越常见,原因是它既考DFS枚举能力,又考二分和排序的综合运用。
4. 笔试环境里最容易翻车的细节:输入输出、复杂度、语言选择
4.1 输入输出与自测陷阱
很多人刷题用LeetCode,习惯了函数式编程,输入输出由平台处理。但美团笔试用的是牛客网这种OJ,你需要自己写完整的输入输出解析。第2场笔试我就看到评论区有人问“为什么我的代码本地跑得好好的,提交就是0分”,大概率是输入解析出了问题。
美团笔试的输入可能是多行,第一行是数据组数T,后面跟着T组测试数据;也可能第一行是N和M,然后M行给出边关系。你需要用while循环读取到EOF,或者用getline处理带空格的字符串。我建议提前准备几个模板:
- Python的
sys.stdin.read().split()可以一次读取所有token,按需取用,简单高效。 - Java用
BufferedReader,不要用Scanner,因为数据量大时Scanner很慢。 - C++用
ios::sync_with_stdio(false); cin.tie(0);,不然可能因为I/O超时。
另外,自测的时候不要只测题目给的样例。你要自己构造极端数据:大量输入、重复数据、边界值。我当时每写完一题,都会在本地跑三组数据:最小规模(n=1)、最大规模(n=10^5或10^6)、以及一个完全随机的数据。跑完再提交,AC率会明显提高。
4.2 复杂度估算与超时处理
第2场笔试的超时惩罚很残酷。同一道题,O(n^2)可能只能过20%的数据,O(n log n)才能全过。所以动笔之前,一定要先看一眼数据范围。如果n是10^5,那基本排除O(n^2)的算法;如果n是10^3,O(n^2)可以接受,但不要写O(n^3)。这个估算能力只能靠平时刷题时养成习惯:每刷完一道题,都看一眼官方题解的时间复杂度,然后对比自己的做法。如果你的做法复杂度差了一个量级,即使AC了,也要重新思考一遍更优解法。
遇到不确定会不会超时的情况,可以写一个“暴力+优化”的混合版本。比如第一版先写暴力的双层循环,保证小规模数据能过;然后针对大规模数据加一个if n > 10000的分支,用哈希表或排序优化。这种“踩线策略”在笔试中很实用,至少能拿部分分。
4.3 多语言选型建议
美团笔试允许使用主流语言,但不同语言在竞赛里的表现差异很大。我建议你只用自己最熟练的语言,不要因为别人说C++适合竞赛就临时切换。C++的优势是STL和运行速度快,适合图和DP的复杂实现;Python的优势是写代码快、调试方便,适合前两道简单题,但在大数据量场景下容易卡常数;Java综合起来也可以,只是代码量偏多。
我个人在美团第2场用的是C++,因为很多图论模板直接套STL就行。如果你用Python,务必学会使用sys.stdin.buffer.read()做快速输入,并且尽量少用递归,因为Python的递归深度默认只有1000,遇到DFS遍历时会挂。一个折中的办法是改用栈模拟DFS,或者直接用sys.setrecursionlimit(1000000),但这个操作在OJ上不一定稳定。
5. 结合第2场风格,聊聊实际的备考路径
5.1 刷题策略:以“模型归纳”代替“题号堆量”
针对美团的出题风格,我建议你在刷题时不要只追求AC,而是每做一道题,在旁边写下这个题目对应的“抽象模型”。比如“区间合并问题:排序+扫描”“带权区间调度:排序+DP+二分”“拓扑排序最长路:入度队列+DP”。积累到一定量后,你会发现题目千变万化,但模型就那么几十种。
我自己在秋招前整理了40个核心模型,覆盖了数组、字符串、链表、树、图、动态规划、贪心、搜索、数学。每天复习10个模型,并结合一到两道新题验证。这个方法比每天无脑刷5道题更有效,因为笔试考的是你在压力下快速匹配模型的能力。美团第2场正好验证了这一点:只要模型匹配得准,代码实现其实是水到渠成的事。
5.2 最后两周的冲刺时间表
如果距离笔试还有两周,我的建议是分阶段安排:
- 第1-7天:按专题刷题。每天固定一个专题,比如周一贪心、周二区间DP、周三拓扑排序、周四状态压缩、周五模拟+字符串、周六综合模考、周日复盘错题。
- 第8-11天:每天找一场完整笔试或模拟题集,完全按照考试时间限制来做。重点不是分数,而是训练“快速跳过难题”和“分配时间”的能力。
- 第12-14天:只复习错题和核心模板,不再做新题。同时准备一份自己的输入输出模板、常用算法代码片段,比如快读、二分、并查集、拓扑排序。考场上直接复制粘贴,能省下大量时间。
这是我实际用过的时间表。它最核心的价值是模拟了真实的考试节奏,而不是让你沉浸在“我已经刷了500题”的虚假安全感里。
5.3 心态与现场应对:把会做的题做快,比死磕难题更值
最后聊聊心态。校招笔试不像高考,不需要每道题都拿满分。美团这类大厂的笔试通常是筛选性质,你只要超过一定比例的人就能进入面试。所以遇到不会的题,不要慌张,更不要盯着屏幕发呆。我当时的原则是:
- 如果一道题超过15分钟没有形成明确的算法思路,立刻去看下一题。
- 所有会做的题先拿满,再回头考虑难题的暴力解。
- 即使只能写出O(n^2)的暴力代码,也要把代码写完整,因为部分分也很关键。
第2场笔试的压轴题我当时只写出了双向搜索的框架,没有优化到满分,但前两题AC,第三题拿了大部分分,最后还是顺利拿到了面试邀请。这也验证了一点:比赛比的不是单题极限,而是整体得分。备考阶段多做“整套题”的模拟,比只刷单题更能培养这种全局观。
我个人体会最深的是,美团2023校招技术第2场编程题并不是在考“偏题怪题”,而是在考你对基础模型的熟练度和考场上的决策力。如果你正准备今年的秋招,建议先拿历年真题或者模拟套题做一次自我摸底,找准自己的薄弱专题,然后按照上面的思路集中突破。这样上场时心里才有底。