免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

美团笔试复盘:四大算法题型与ACM模式实战指南

美团笔试复盘:四大算法题型与ACM模式实战指南 2023年美团秋招编程岗第二批笔试我是九月初那场考的。当时同时投了美团到店和美团优选两个部门笔试是同一场通用卷做完之后最大的感受是美团的编程题不像字节那么追求奇技淫巧式的难题也不像腾讯那样喜欢考特别大的系统设计它的题目更贴近业务包装得很生活化但内核还是那些经典算法。如果只看题面就动手容易被冗长的业务场景带偏但只要拆开包装看到本质难度其实不算离谱。这篇文章不是官方解析也不是标准答案而是基于我自己考后复盘、和几个同批参加笔试的同学对题之后整理出来的经验总结。我会把题型分布、出题套路、几道典型题目的完整思路、选择题的复习重点、ACM模式下的输入输出坑、以及考前最后一个月的时间线全部写下来。准备投美团或者正在准备秋招的朋友这篇应该能帮你少走不少弯路。1. 先摸清美团笔试的真实结构和筛选逻辑美团笔试的场次安排一般是8月中旬开始一直持续到10月底分批进行。第二批次的时间通常在9月上旬和第一批次最大的区别是题库完全换了但题型框架基本不变。我当时是在牛客网上做的双机位全程摄像头监控不能切屏切屏次数超过三次系统会直接提醒严重的会被判作弊。整个笔试时长一般是90分钟到120分钟视批次而定。我考的这批是120分钟题量构成是单选题20道左右编程题4道。单选题每题大概1.5分编程题占大头总分100分里编程题大概占60分以上。所以哪怕选择题错一半只要编程题AC两道以上基本都能进面试。这里有个关键信息美团笔试不设最低通过线它看的是相对排名。同一批次的候选人放在一个池子里按分数排名排名靠前的才有面试机会。所以你要跟同期做题的人比而不是跟自己比。这就意味着遇到一道大家都做不出来的难题你只要能做出暴力解法拿部分分就比交白卷的人强很多。从2023年这一批来看编程题难度梯度非常明显第一题属于送分题基本数据结构操作二十分钟内解决第二题是经典动态规划或贪心中等难度第三题开始上强度一般是二分答案、图论或者复杂DP第四题属于压轴题能做出来的基本都是少数人。我当时第一题做了十几分钟第二题卡了半小时第三题用暴力水了部分分第四题看了一眼直接放弃最后也进了面试。所以我的建议是做题顺序别按题目顺序来先把四道题都快速扫一遍从最简单的开始做保证每道题都能拿一部分分数。2. 编程题到底考什么四类核心算法的出题套路拆解先说结论美团笔试编程题的高频考点集中在四类——贪心与排序、动态规划、二分答案、图论与并查集。这四类是美团笔试的四大金刚基本每批都会出现至少两到三类。下面结合我考到的题目结构逐个拆一下这些考点的出题套路和应对策略。2.1 贪心与排序送分题的最爱第一题基本是贪心或者排序而且往往套一个业务场景。我考到的第一题大意是给一批订单分配骑手每个骑手只能接两个订单订单有一个配送时长问怎么分配让最大配送时长最小。剥掉外卖外壳之后其实就是给定一个数组两两配对让每对之和的最大值最小经典做法是排序后首尾配对。这种题的核心套路是遇到最值问题且没有明显后效性时优先考虑能不能排序后贪心。贪心题不要试图证明大胆猜结论然后写代码笔试环境没人要求你证明贪心正确性只要提交通过就是对的。但在平时练习时还是要补上证明因为这直接影响面试环节手撕算法时跟面试官交流的质量。2.2 动态规划中档题的中流砥柱第二题基本都是DP而且背包问题出现频率极高。美团业务里有大量优惠券组合预算分配资源调度场景这些抽象出来都是背包。我当时那道题大意是用一定金额买食材每种食材有热量和价格要在不超过预算的情况下让总热量最大标准的0-1背包。背包类题目在笔试中的变体很多可能是完全背包每种物品无限取、多重背包有限个数、分组背包每组只能选一种。美团笔试几乎不会在背包的板子上为难你真正的难点在于识别出这是一个背包问题以及设计状态转移方程。给一个实用技巧看到题面出现在不超过X的情况下最大化Y或者恰好凑出Z的描述第一反应就应该是DP状态维度一般是前i个物品剩余容量或已选容量。2.3 二分答案区分度最高的一类题第三题开始进入真正的分水岭二分答案是这里的常客。美团特别爱考这类题因为它在业务中极其常见——比如问最大配送时长能否控制在X小时内最小化最大负载是多少本质都是先猜一个答案再用贪心或模拟验证这个答案可行性然后二分搜索。我当时第三题是把n个数字分成m段让每段和的最大值最小——裸的二分答案关键在check函数贪心分组如果当前段和超过mid就新开一段最后看段数是否小于等于m。但我当时没写好用的暴力深搜只过了部分用例。复盘后发现这类题其实有固定模板练熟之后是一道性价比很高的题。2.4 图论与并查集压轴题的常客第四题的出题范围通常是图论尤其是并查集和最短路径。美团业务里商家、骑手、用户之间的关系天然适合用图来建模所以并查集在笔试中出场率不低。常见场景是给一堆顶点之间是否存在边判断连通性或者动态加边问两个点是否连通。并查集模板本身非常简单十几行代码难就难在怎么识别出题面在考并查集。我给一个比较实用的判断标准题目中出现连通分组根节点朋友关系传递这些词就往并查集想。如果要算最短路径或者最小生成树题目一般会明确提到路径边权等字眼不会太隐晦。3. 三道典型题目的完整复盘从读题到AC的思路过程这一节我把考后跟同学对出来的一些典型题目复原出来着重讲一下完整的思考链路而不只是贴代码。真正有价值的不是背代码而是学会看到题面怎么一步步拆解。3.1 第一题骑手分段配送排序后首尾配对题面大概是给定n个订单的配送时长数组每个骑手最多接两个订单一个骑手完成的耗时为这两个订单耗时之和问所有骑手里最大耗时的最小值是多少。n是偶数范围大概在10^5级。这道题看起来有牛客的味道其实思路就是排序贪心。把耗时从小到大排序然后第一个最小和最后一个最大配对、第二个和倒数第二个配对依此类推。这样每对的和会尽可能均匀最大和就是答案。n int(input()) nums list(map(int, input().split())) nums.sort() ans 0 for i in range(n // 2): ans max(ans, nums[i] nums[n - 1 - i]) print(ans)这段代码就是全部。说下为什么首尾配对是最优的如果不让最大值和最小值配对那最大值必然会和一个更大的数配对这个对的和一定比首尾配对大所以不会更优。这就是反证法的思路几句话就能说服面试官。3.2 第二题预算与热量0-1背包的标准变体题面大意小美有m元预算要去买n种食材每种只有一份每种食材有一个价格cost[i]和一个热量value[i]问在总花费不超过m的情况下能获得的最大总热量是多少。标准的0-1背包把m看成背包容量每个食材的花费看作体积热量看作价值。用一维滚动数组优化从大到小遍历容量避免重复选取。public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); int n sc.nextInt(); int m sc.nextInt(); int[] cost new int[n]; int[] value new int[n]; for (int i 0; i n; i) { cost[i] sc.nextInt(); } for (int i 0; i n; i) { value[i] sc.nextInt(); } int[] dp new int[m 1]; for (int i 0; i n; i) { for (int j m; j cost[i]; j--) { dp[j] Math.max(dp[j], dp[j - cost[i]] value[i]); } } System.out.println(dp[m]); } }我当时的做法基本就是这段代码。需要注意一个点循环容量时从m到cost[i]递减这是因为如果正序同一个食材会被重复选那就变成完全背包了。笔试中很多人都是栽在这个细节上本地测试一个用例看不出问题数据大了就WA。3.3 第三题分段最大值最小化二分答案的经典模板题面大意给定一个长度为n的数组和一个整数k要求把数组切成恰好k段每段连续求所有切法中每一段的和的最大值的最小值是多少。这就是那个著名的LeetCode 410题的变体也是美团笔试题的标配之一。核心思路是二分答案猜测一个答案mid检查能否在不超过mid的条件下切成k段甚至更少。如果能说明答案可以更小如果不能答案必须更大。n, k map(int, input().split()) arr list(map(int, input().split())) def check(mid): cnt 1 cur 0 for x in arr: if cur x mid: cnt 1 cur x else: cur x return cnt k left, right max(arr), sum(arr) while left right: mid (left right) // 2 if check(mid): right mid else: left mid 1 print(left)我在这题上栽的跟头很典型忘记初始化cur时直接令cur0而不是第一个元素导致第一段的累加逻辑出错。这种错误在平时刷题时可能不会注意到但在笔试的紧张状态下特别容易出现。建议考前专门练几道需要注意边界初始化的二分题把状态初始化这种低级失误降到最低。4. 选择题部分不止背八股更考理解编程题虽然占分大但选择题的20道也不能完全放弃。美团的单选题覆盖计算机网络、操作系统、数据库、Java/Go语言、数据结构与算法。整体难度体系是这样的40%是纯记忆型的八股文40%需要简单推导剩下20%是容易踩坑的概念辨析题。4.1 计算机网络TCP和HTTP是绝对重点选择题里网络部分大概会出两三道主要集中在TCP的三次握手与四次挥手、拥塞控制的状态机、HTTP状态码的含义。美团毕竟有大量Web业务这些是基础能力考核。常见考点有TCP的TIME_WAIT状态为什么需要等待2MSL、拥塞控制里慢启动和拥塞避免的阈值区分、HTTP 301和302的区别、Cookie和Session的关系。这些内容不偏把计算机网络经典教材的TCP章节复习透彻基本就够。一个容易错的点题目问HTTP/1.1相比HTTP/1.0新增了什么时很多人只想到Keep-Alive忘了它还支持Host字段、断点续传和缓存机制。选择题的迷惑选项往往会把这些混在一起。4.2 操作系统进程线程、死锁、虚拟内存操作系统选择题通常会有一道关于死锁的比如下列哪个条件不是死锁产生的必要条件或者银行家算法的目的是什么。备考策略很简单把死锁的四个条件互斥、占有且等待、非抢占、循环等待记牢再理解银行家算法是避免死锁而不是预防死锁。还会考到页面置换算法比如LRU、FIFO、OPT的比较。这里需要注意美团的选择题很喜欢给一个小场景比如访问序列为1,2,3,4,1,2,5,...内存块数为3问LRU替换几次缺页这种题就是纯模拟必须自己动手画一遍才能拿分。4.3 数据库索引和事务隔离级别数据库题目不算多一般一到两道但区分度明显。我遇到的是聚簇索引与非聚簇索引的区别以及事务隔离级别里可重复读和读已提交在多版本并发控制下的差异。这里给一个核心理解索引为什么用B树而不是B树因为B树所有数据都在叶子节点而且叶子节点之间用链表连接非常适合范围查询。美团业务里有大量订单列表查询这种场景下B树的优势特别明显。如果你能从这个角度回答选择题而不是死记B树层数少正确率会高很多。4.4 数据结构与语言基础大厂最爱的那几个点数据结构部分一定会有哈希表冲突处理方式链地址法、开放定址法、二叉搜索树与平衡二叉树的区别、栈和队列的应用场景。语言方面如果投的是Java岗会考Java内存模型、HashMap的扩容机制、ConcurrentHashMap的锁分段如果是C岗vector扩容机制、智能指针、虚函数表都是高频考点。我当时的经验是选择题里最难的其实是下列代码输出的结果是什么这类题很考验对语言特性的掌握。考前我花了一个晚上专门过了一遍Java中Integer缓存池-128到127的坑、String的intern方法、数组和ArrayList的转换注意事项结果真的碰到了一道类似的题。5. ACM模式与笔试环境90%的人挂在输入输出上很多人在牛客上刷题都是用IDE自己写main函数一到笔试就发现题目要求完整读入读出一个ACM模式。这个模式对在校生来说最大的坑是不需要实现某个方法而是自己写完整的main/read/print逻辑输入一行读一行输出不能有多余字符。5.1 三种语言的高频输入输出模板Java用Scannerimport java.util.*; public class Main { public static void main(String[] args) { Scanner sc new Scanner(System.in); while (sc.hasNext()) { int n sc.nextInt(); int[] arr new int[n]; for (int i 0; i n; i) { arr[i] sc.nextInt(); } System.out.println(solve(arr)); } } }Python直接用input和splitimport sys def solve(arr): pass if __name__ __main__: data sys.stdin.read().split() # 按位置解析C用cin和cout注意取消同步#include bits/stdc.h using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin n; vectorint arr(n); for (auto x : arr) cin x; cout solve(arr) endl; return 0; }一个我踩过的坑Java的hasNext()和hasNextLine()混淆会导致死循环或者读不出数据。建议考前一晚上把牛客网上的输入输出练习完整做一遍熟悉多行输入、多组输入、字符串中带空格的三种常见场景。5.2 没给样例提示时怎么自己造数据验证笔试不像LeetCode有Run Code可以先跑一遍牛客一般只有提交按钮最多给你一两个示例。我的经验是写完代码后在本地IDE上先自己跑几组极端数据比如n1的最小情况、数组全部相等的情况、数组长度很大的情况看是否超时。这些边界情况往往是隐藏用例的最爱。比如上面说的分段问题如果数组长度为1、k也为1那答案就是数组唯一的那个元素。如果数组里有元素大于二分答案的下界max(arr)说明下界设置错了因为任何一段的和都不可能小于单个元素的最大值。这些小细节自己平时跑测试用例时想得到考场上紧张了很容易忽略。5.3 关于切屏和代码调试的建议很多笔试平台对操作有监控。我当时看到一条规则不允许在考试期间打开本地IDE之外的任何代码编辑器或搜索引擎。我个人建议不要在笔试时尝试去IDE里写大段代码再复制到网页里提交一旦有嫌疑后台检测到剪贴板跨应用操作可能会被判违规。直接在网页的编辑器里写写完原地调试最稳妥。但网页编辑器的自动补全很弱所以平时练习时就要锻炼裸写能力。我备考时做了一个调整前两周用IDE写后两周专门在牛客网的编辑器里写强制自己适应没有智能提示的环境。这个习惯很枯燥但非常有用因为笔试真的就是在这个环境下进行的。6. 备战美团笔试的四周时间线从刷题到模拟实战这一节是很多朋友私信问得最多的还有一个月考美团到底该怎么规划我根据自己从投简历到笔试这四周的实际安排整理了一条可以照抄的路线但每个人的基础不同时间线可以做相应调整。6.1 第一周摸底和打基础先用两三天把高频算法全部过一遍。建议按顺序复习数组与链表操作、栈与队列、哈希表、二叉树遍历、排序和二分。然后集中刷贪心和动态规划尤其是背包类和区间类问题。不用贪多每天保证五道题以上前三天可以简单一点后三天开始做中等难度。这个阶段最容易犯的错误是只看题解不动手。我见过太多人把题目收藏了就以为会了。刷题的关键是合上答案自己写一遍哪怕写得慢也要让脑子真正跑一遍状态转移的过程。第二天可以试试不看答案重写前一天的题能写出来才说明真的掌握了。6.2 第二周专项训练和限时模拟第二周开始按模块特训重点是二分答案和并查集。美团笔试爱考这两种但很多同学平时刷题的时候因为这两类题不如链表和栈直观容易回避。我个人的方法是每周三和周日做一次限时模拟直接拿牛客上历年的美团笔试题来练严格设120分钟闹钟跟真实考试一样不允许切屏、不允许暂停。模拟完之后最重要的不是对答案而是统计每道题的耗时和卡住的点。我当时统计下来发现自己在输入输出上平均浪费了十几分钟后来专门用一天练输入输出模板第二周模拟时就快了很多。6.3 第三周错题复盘和知识盲区补充到了第三周不需要再大量刷新题了。把前两周做过的所有题重新看一遍尤其是那些看了题解才会做的题。我当时做了一个简易表格把所有错题按考点分类统计出自己最薄弱的三类区间DP、带权并查集、二分边界处理。然后针对这些点再补充练习。这一周还有一个重要任务把选择题的八股文内容系统过一遍。我用的方法是把牛客上别人整理的面经题集复制下来每天早晚各背一遍重点记那些容易混淆的数字和概念比如TCP的2MSL是4分钟MSL默认2分钟、HTTP 429状态码的含义、Linux中chmod 755的属性等。这些纯记忆的分数考前一周突击性价比最高。6.4 第四周稳住节奏和调整状态最后一周不需要再做难题了。每天固定做两道简单题保持手感然后空出时间复习自己的错题本。我个人的安排是上午做一套选择题下午写两道编程题晚上复盘题解中的优化思路不看新题。考前两三天要注意作息。笔试虽然是线上进行但精神状态直接影响代码水平。我因为考前熬夜看题解到正式笔试时头脑昏沉第二道DP题的状态方程推了半天才反应过来。第二次参加下一批补招时考前早睡状态好了不少同样难度的题目很快就做完了。6.5 一个关于要不要海投的补充建议如果你同时投了多家大厂笔试时间可能会冲突或者很密集。我的建议是美团笔试要认真准备因为它的题目风格比较主流练一次就能覆盖大多数互联网公司的笔试范围。即便这次没过也能积累一套通用的笔试经验后面百度、京东、快手的笔试套路大同小异。把每一场笔试都当成免费的模拟考心态上会轻松很多也不容易因为一场失利而崩盘。7. 考后复盘我最后悔的那30分钟写这篇文章时我不打算回避自己犯过的错误。考完后我把整场笔试的答题轨迹重新梳理了一遍发现自己最大的问题不是算法不行而是做题策略太死板。当时我看到第一题比较简单做完后心情不错就顺着顺序做第二题。第二题卡在把每种食材只有一份翻译成0-1背包的建模上——题面没有直接说每件物品只能选一次而是在场景里描述了每种食材库存只有一份我习惯性地把它当成了完全背包写了个三重循环样例过了但复杂度爆了大用例直接超时。如果当时我能先花30秒扫一眼后面几道题意识到第三题是二分答案模板题、第四题是并查集模板题就应该果断先跳过第二题把后面的模板题先AC掉再说。因为模板题的分数是确定的而DP题即使想对了解法也可能因为边界条件调半天。这个先做送分题再做中等题最后做难题的顺序说了无数次但真正能执行好的人很少包括我自己也没做到。现在回想这30分钟的损失不仅仅是第二题没拿满分更打乱了整体节奏导致后面看第三题时心里很急躁check函数写错了两次才调通。所以最后给所有准备参加美团笔试的朋友一句实在话算法功底决定你的天花板但做题策略和心态决定你能发挥出几成。考前刷题固然重要考场上能不能冷静地把会做的题都拿下往往才是进不进面真正的分水岭。希望这篇复盘能帮你在考场上少走一点弯路把该拿的分都牢牢攥在自己手里。
返回列表