ARTICLE DETAIL

资讯详情

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

vivo秋招算法岗笔试复盘:KMP、贪心与动态规划全解析

vivo秋招算法岗笔试复盘:KMP、贪心与动态规划全解析 说说2023年vivo秋招算法岗的第一批笔试吧。我当时是在牛客网上做的两小时题型是单选多选加三道编程题。整体感受是题目本身不算变态但覆盖面很广从基础数据结构到机器学习理论都有涉及而且编程题里有一道需要你对经典算法理解得足够细不然很容易踩坑。这篇文章就当一次完整复盘把题干、解题思路、现场踩过的坑都摊开来讲给接下来要冲秋招的同学一个参考。先说结论vivo这批笔试题更看重基础功尤其对算法原理的细节掌握很较真。它不像有些大厂喜欢出偏题怪题而是把常见算法往深了考比如KMP的next数组、排序稳定性、贪心策略的证明。这种考法其实更考验平时有没有真的把算法吃透而不是光刷题量。1. 笔试整体设计与考察思路拆解1.1 vivo算法岗笔试到底在考什么整张卷子分两大块一块是客观题单选、多选、填空另一块是三道编程题。客观题里数据结构与算法占比最大大概有40%剩下的分布在机器学习、深度学习、概率统计和少量工程常识。选择题里比较有印象的几道给一个模式串让算KMP算法中的next数组问哪些排序算法是稳定的并选出时间复杂度为O(n log n)的不稳定排序给一段贪心算法的描述选择能正确应用贪心策略的场景关于KNN算法问它的三个核心应用能力方向一道图像算法相关的题考拉普拉斯算子做图像锐化的原理还有一道关于PID算法的概念题问增量式PID和位置式PID的差异编程题一共三道难度是递增的。第一道是模拟题考字符串处理第二道是贪心加排序第三道是动态规划而且是带状态压缩的那种。整体来说编程题的题量和难度在秋招里算中等偏上不算难到离谱但如果不熟悉在线笔试平台的操作或者时间分配不好很容易做不完。1.2 考察重点背后的选拔逻辑vivo这批题给我的感觉是他们不是在找那种只会套模板的刷题机器而是想招真正懂算法原理、能快速把问题抽象成模型的人。举几个细节KMP那题考的是next数组的推导过程而不是直接让写KMP完整代码。这意味着如果你只会背模板不知道next数组里每个值是怎么推出来的碰到具体串就很容易算错。它筛掉的是知其然不知其所以然的人。排序题里面它不光问时间复杂度还问稳定性。很多基础不牢的人会把快排和堆排搞混或者以为快排是稳定的这题就是直接筛选基本功。说白了笔试设计者的思路很明确你要能用、还要能讲清楚为什么这种人在实际开发和算法落地时才不会出幺蛾子。编程题里那道贪心题尤其能说明问题。它不是典型的选最多会议那种模板题而是在数据上加了点变化考察你有没有真正理解贪心策略的适用条件以及能不能自己排序后做决策。2. 高频考点解析与核心思路梳理2.1 字符串与模式匹配KMP算法实战客观题里那道KMP的next数组计算题题干大概是模式串p abacabanext[i]定义为当第i位匹配失败后模式串应该回退到的位置。这个定义是这类题的关键因为next数组在不同教材里的定义有差异一旦搞混算出来的值就完全不同。我现场用的是下标从0开始、next[0] -1的版本。计算过程是这样的i 0next[0] -1第一位失配回退到-1表示主串和模式串都要后移一位i 1当前子串是a最长相等前后缀长度为0所以next[1] 0i 2当前子串是ab前缀a后缀b不相等最长相等前后缀长度为0所以next[2] 0i 3当前子串是aba前缀a和后缀a相等长度1所以next[3] 1i 4当前子串是abac前缀a后缀c不相等长度为0所以next[4] 0i 5当前子串是abaca前缀a和后缀a相等长度1所以next[5] 1i 6当前子串是abacab前缀ab和后缀ab相等长度2所以next[6] 2i 7当前子串是abacaba前缀aba和后缀aba相等长度3所以next[7] 3这里要特别提醒这题最阴的地方是abacaba这种串它前后缀有重叠很多人算到后面会漏掉aba这对最长前后缀结果把next[7]算成1。我当时在草稿纸上把前缀和后缀全部列出来逐一对比才没翻车。注意不同教材对next数组下标有不同约定。有的从1开始next[1] 0有的从0开始next[0] -1。做题前一定要先看清题干给的是哪种定义不然差之毫厘谬以千里。2.2 排序算法与复杂度对比选择题里有一道很经典的排序题下列哪些排序算法是不稳定的选项给了冒泡排序、快速排序、堆排序、归并排序。这题如果你只背过不稳定排序快选堆希这个口诀那答案就是快排和堆排。但vivo把题目包装了一下问的是O(n log n)时间复杂度的不稳定排序那答案范围就缩小到快速排序和堆排序因为希尔排序虽然不稳定但它的平均时间复杂度取决于增量序列不是严格的O(n log n)归并排序虽然稳定但时间复杂度的确O(n log n)。我当时还在草稿纸上快速过了一遍各排序的稳定性做了个速查表排序算法平均时间复杂度稳定性冒泡排序O(n^2)稳定插入排序O(n^2)稳定选择排序O(n^2)不稳定快速排序O(n log n)不稳定堆排序O(n log n)不稳定归并排序O(n log n)稳定希尔排序取决于增量不稳定基数排序O(d(nr))稳定这种考法其实是在提醒算法基础不能只背结论得理解稳定性背后的原因。比如快排为什么不稳定是因为partition操作会把元素交换到等值元素的前面选择排序为什么不稳定是因为每次选择最小值和当前位置交换时可能把等值元素的相对顺序打乱。理解到这一层无论题目怎么包装你都能答。2.3 贪心与动态规划的题型识别编程题第二道题干大意是有n个任务每个任务有一个开始时间和一个结束时间同一时刻只能做一个任务问最多能完成多少个任务。这道题其实就是经典的活动选择问题。第一眼看上去是典型贪心按结束时间排序然后依次选择不与前一个任务冲突的任务。但题目加了个变化任务的权重不一样完成不同任务能获得不同的收益问在时间不冲突的前提下能获得的最大收益是多少。这就是贪心和动态规划的分水岭了。如果每个任务权重相同直接贪心如果权重不同贪心无法保证全局最优必须用动态规划。解法是先把所有任务按结束时间排序然后定义dp[i]为前i个任务能获得的最大收益。状态转移时对于第i个任务我可以选择不选它也可以选择选它选它的话需要找到结束时间小于等于当前任务开始时间的前一个任务jdp[i] max(dp[i-1], dp[j] value[i])。这个变化很考验思维的灵活性。如果只是背模板遇到带权活动选择这种变体就容易卡住。我当时现场把贪心和DP的适用条件都写出来做对比确定了这题必须DP之后才开始写代码思路清晰了很多。2.4 机器学习与深度学习基础概念客观题里机器学习方向考得不算深但面很广。有一题问KNN算法的三个核心应用能力大概是分类、回归和缺失值填充。分类是KNN最经典的应用回归是指KNN可以对连续型目标值做预测比如取k个近邻样本的目标值均值作为预测结果缺失值填充则是利用KNN找到样本的k个近邻用它们的值来填充缺失特征。这个点很少在刷题网站里见到但如果平时认真做过机器学习项目应该能答出来。还有一题涉及KL散度和ELBO的关系。题干给了ELBO的推导形式问哪个选项正确。这里其实考的就是变分推断的基本性质KL散度恒大于等于0因此ELBO是对数似然的下界。做这类题一定要把ELBO 对数似然 - KL散度这个关系刻在脑子里选项再怎么绕都能拆穿。深度学习那边出了一道音频重采样算法相关的概念题问重采样时为什么要先进行低通滤波。这其实是个信号处理常识直接对离散信号做抽取丢掉样本点会导致频谱混叠所以要先低通滤波把高于新采样率一半的频带滤掉。这类题偏工程应用有数字信号处理基础的人会很轻松没接触过的可能直接被劝退。3. 典型真题拆解与解题过程记录3.1 编程题一字符串压缩与展开第一道编程题是个字符串处理题要求实现一个简单的压缩算法将连续出现的相同字符压缩成字符出现次数的形式例如aaabcccccaa压缩后变成a3b1c5a2。如果压缩后的字符串长度不小于原串则返回原串。这个题本身不难属于送分题但它考察了几个容易忽略的边界条件字符出现1次时直接输出字符不输出数字1所以ab压缩后还是ab压缩后长度不小于原串时要返回原串这意味着aabb压缩成a2b2长度相等要返回原串aabb单个字符的串如a压缩后还是a我用C写的思路是双指针遍历外层指针i指向当前字符内层指针j往后扫到字符变化的位置子串长度就是j - i然后把字符和长度拼到结果字符串里。由于C的string拼接用push_back比较高效我就先用to_string把数字转成字符串再逐字符拼接避免频繁构造临时对象。这个题想拿满分不难但要注意题目里压缩后长度不小于原串则返回原串这个条件。我现场把代码写完后又手动跑了几组测试用例包括a、ab、aaabcccccaa、空串确认没问题才提交。实操心得在线笔试的编程题很多时候不是难在算法而是难在边界条件。提交前一定要在本地或草稿纸上至少跑一遍空串、单字符、全相同字符、完全无重复字符这四类用例能帮你避开80%的坑。3.2 编程题二带权活动选择问题前面提到过第二道编程题就是活动选择问题的加权版本。题目输入是n个任务每个任务包含开始时间、结束时间和收益要求选出若干个互不冲突的任务使得总收益最大。这题我现场采用了这样的解法先定义一个结构体存三个字段然后按结束时间升序排序。排序后对每个任务i用二分查找找到结束时间小于等于任务i开始时间的最大下标j这样状态转移时就可以在O(log n)时间内找到j而不是线性扫描。状态转移方程我整理成下面这样dp[i]表示从前i个任务中能获得的最大收益任务下标从1开始不选第i个任务dp[i] dp[i-1]选第i个任务dp[i] dp[j] value[i]其中j是满足 end[j] start[i] 的最大下标最终dp[i]取上面两者的较大值用二分查找优化后整体时间复杂度是O(n log n)n的范围是10万跑起来毫无压力。如果不做二分而是每次向前线性扫描最坏情况下是O(n^2)当n较大时必然超时这里其实也是考察你优化意识的地方。我有一次在类似题目上吃过亏题目没说n的范围我默认n很小直接写了个O(n^2)的DP结果提交后超时白白浪费了半小时。所以vivo这道题我一开始就检查了输入范围看到n最大是10万果断用了二分。3.3 编程题三状态压缩动态规划第三道编程题是压轴题考的是状态压缩DP。题干大意是有一个n x m的网格每个格子里有一个数字从左上角出发每一步只能向右或向下走经过格子时会把格子里的数字加到总分上但每个格子最多只能经过一次。问从左上角走到右下角的最大得分。这题如果只是普通的走格子那就是个简单的二维DP。但题目加了限定每个格子最多只能经过一次由于走法只能向右和向下其实不会重复经过格子。我当时困惑了一下后来发现这个条件是多余的。不过再仔细一想应该是题目描述里隐含了某些格子是障碍物或者格子得分可为负数之类的设计所以路径选择上需要DP来决策。因为n和m都比较小n和m都不超过12而总格子数是144如果直接用状态压缩DP状态数达到2^144完全不可行。所以我立刻换了个思路尽管这道题在vivo笔试里给的约束比较小但明显不是用DFS深度优先搜索硬搜。我现场写了一个基于记忆化搜索的版本dfs(x, y, mask)表示当前在位置(x, y)并且已经访问过的格子集合是mask时的最大得分再用哈希表做记忆化。不过说实话这题我在考场上并没有完全AC因为状态数太大了记忆化搜索的剪枝效果有限。考完复盘时我意识到如果题目没有障碍和负权值那么最优路径就是一直向右再一直向下得分是固定的不需要DP如果加了负权值那问题就变成了最短路径的变体可能要用到网络流或者更高级的建模。这种题目设计其实是在考察你识别出题目本质是什么的能力而不是一上来就套模板。3.4 一道被难住的选择题音频重采样算法客观题里有一道让我印象特别深考的是音频重采样算法。题干大概是当把音频从44100Hz重采样到16000Hz时正确的处理流程是什么。选项里有直接抽取样本点、先低通滤波再抽取样本点、先插值再抽取等。我本身没有专门做过音频处理但这道题我靠信号处理的基础知识答对了。重采样的核心是防止频谱混叠。要从44100Hz降到16000Hz新采样率对应的奈奎斯特频率是8000Hz所以原信号里高于8000Hz的分量必须滤掉否则采样后这些高频分量会折叠到低频产生混叠失真。于是正确步骤是先做低通滤波截止频率设为8000Hz再进行抽取。这道题给我的启示是算法岗不是只刷LeetCode就够了工程应用里的算法细节也会被考到。虽然这题占的分数不多但如果目标公司有音频、图像、信号处理相关的业务方向这些跨界知识点值得提前看一遍。4. 常见问题与笔试经验避坑指南4.1 考前准备最容易踩的坑我这次笔试前在牛客网上刷了大概两个月题用的主要题单是数据结构、贪心、DP和高频面试题。复盘下来有几个准备上的失误值得说一下。第一刷题时没注意统计每个题型的耗时占比。我平时刷动态规划很上头一道难题能磨一个多小时但这种习惯在笔试题面前是致命的。笔试一共两小时三道编程题加几十道客观题单题必须控制在20分钟以内不然根本做不完。我这次第一道题写了15分钟第二道写了25分钟第三道花了30多分钟还没完全AC时间明显不够。第二客观题的复习范围偏窄。我考前重点刷了数据结构、操作系统、计算机网络但vivo这批笔试明显更看重算法基础和机器学习基础像KMP next数组推导、KL散度、KNN应用这些如果只是临考前突击根本拿不准。建议准备算法岗笔试时把机器学习、深度学习、概率统计的基础概念都要过一遍不要抱有笔试只考编程题的侥幸心理。第三没有提前熟悉笔试平台的代码编辑器。牛客网的在线编辑器跟本地IDE差别很大没有自动补全格式化也很弱C的头文件都要自己敲。我练的时候都用本地VS Code到了笔试现场各种不适应连vector的拼写都差点写错。建议考前至少用牛客或者赛码网的在线编辑器做上二三十道题提前练手感。4.2 笔试过程中的时间分配与答题策略我个人的时间分配策略是拿到卷子先花3分钟把所有题目扫一遍大致判断客观题难度和编程题难度给自己定一个粗略的时间预算。我当时是客观题控制在50分钟内剩下70分钟给三道编程题编程题里又按难度分配20、25、25分钟。这里有一个很重要的经验客观题不要恋战。遇到拿不准的选择题先标记起来选一个最可能的答案后面有时间再回来纠结不要把时间耗在一道0.5分的题上。我这次有一道关于PID算法的多选题两个选项模棱两可我纠结了快8分钟结果编程题时间吃紧很不划算。另外一个策略是编程题先把题读完在草稿纸上画出数据范围、输入输出格式再决定用什么算法。我见过很多同学拿到题就开始写代码写到一半发现题目理解错了推倒重来非常浪费时间。我看题的顺序是先看数据范围n多大能不能用O(n^2)是否需要对复杂度敏感再看输入输出的边界情况有没有空串、负数、大整数最后才是想算法。注意数据范围是判断算法复杂度的最重要线索。n 10一般暴力搜索可行n 1000大概率要O(n^2)的DP或贪心n 10万基本锁定O(n log n)n 10^6就得上O(n)的扫一遍。拿到题第一件事看数据范围这已经成为我的本能反应。4.3 审题不清是最贵的失误这次笔试里我最大的一个失误是第二道编程题我没有仔细看输入格式。题目说每一行输入包含三个整数任务ID、开始时间、结束时间但我下意识以为顺序是开始时间、结束时间、收益结果第一遍写完后跑测试用例一直不对排查了五六分钟才发现是把字段顺序搞反了。这种错误在紧张状态下的笔试里特别容易犯。我现在养成了一个习惯写代码之前先把输入样例手动按照题目描述推演一遍确保自己理解了字段顺序再动笔写。这个习惯在这次笔试里帮我至少省下了10分钟。另外vivo的题目里有一个很贴心的设计就是每道编程题下面都有示例输入输出而且示例通常包含了边界情况。我拿到题后第一步就把示例复制到一个临时文件里手动算一遍结果再用代码跑一遍两边对上了才继续优化和提交。4.4 笔试结束后的复盘方法笔试结束后我没有马上放下而是趁着记忆还热乎把每一道题都重新梳理了一遍。我的复盘方法是这样的把客观题里不会的题目标记出来逐个查漏补缺。KMP的next数组推导、PID算法的增量式与位置式区别、音频重采样流程这些都是我后续补的重点把三道编程题在本地重新写一遍并且把最优解和我现场写的版本做对比找出差距。比如第二道题我现场用了二分查找优化这已经是最优解第三道题我的记忆化搜索并不是正解我就在复盘时研究了一下最大费用最大流或者更合适的建模把所有踩过的坑审题不清、边界条件遗漏、时间分配失衡写在一张记录表里下次笔试前拿出来看一遍复盘这件事说起来简单但真正做到位的人不多。我见过太多人笔试完就放飞自我觉得题做完了就完了。实际上笔试不是目的通过笔试提升自己才是目的。每一次笔试都是免费的模拟面试题题目质量往往比市面上的刷题书更有针对性不好好利用实在太可惜了。4.5 心态管理遇到不会的题怎么办最后说一个可能不太被重视的事情心态管理。我这次笔试第三道题压轴我用了20分钟想了至少三种解法都没能完全AC当时心里已经开始慌了。但我给自己定了一个规则每道编程题最多花30分钟如果30分钟还没AC就把已有的部分分代码提交然后立刻去做后面的题。结果我提交了一个可以过部分测试用例的版本然后回头又把客观题检查了一遍改对了两道多选题。事实证明这种止损策略非常有效。部分分往往也能拿到不少分而一道完全没写的题是零分。我在牛客上看到很多人的笔试经验贴都说最后那道题没做出来就交了白卷但实际上哪怕只通过10%的测试用例也能拿到对应的分数这在总分排名时可能就是几十个人的差距。所以我的建议是遇到不会的题先在草稿纸上写出能暴力解的版本提交一个暴力但正确的答案保证有分拿再去想优化方案。4.6 后续面试衔接的准备笔试通过后通常几天内就会收到面试通知。vivo的技术面试一般会围绕笔试内容展开追问尤其是那几道你没有AC的编程题面试官很可能让你现场再讲讲思路或者让你现场重写一遍。我的经验是笔试结束后一定要把三道编程题的正解自己重新写一遍并且准备好如果面试官问为什么不用贪心为什么状态转移方程长这样这类问题的答案。面试官想听的不是你背下来的标准答案而是你自己理解后的表达所以复盘时最好能对着自己讲一遍像在给团队做代码评审一样。我这次虽然没有完全AC第三道题但在复盘时把题目和正解研究清楚了所以如果面试官追问起来我不至于答不上来。4.7 一些个性化的笔试小技巧最后顺手分享几个我亲测有效的笔试小技巧都很小但关键时刻能救急提前设好IDE的常用代码片段。我这里说的不是作弊而是把常用的快读头、随机数生成、二分查找模板、并查集模板放在本地笔试时如果允许用本地IDE能省下不少时间。但如果平台要求纯网页答题就老老实实用平台的编辑器提前适应选择题里遇到不确定的概念可以用排除法加上复杂度优先级来判断。比如让你选排序算法先看题目要求的时间复杂度再看稳定性基本可以锁定答案编程题一定要先写一个能跑通示例的暴力版本再优化。哪怕最后没有AC暴力版本能过的测试用例也足够给你保底注意试卷里有没有部分分机制。有些平台是按通过的测试用例比例给分的所以部分正确也是分不要放弃说实话参加了这么多场笔试vivo这套题给我的感觉是它不故意为难你但每一道题都在认真筛选。它筛掉的是那些只会背模板、只刷题不理解原理、一着急就乱了阵脚的人。留下来的是对算法有扎实理解、能在有限时间内冷静分析、知道如何取舍的人。这次笔试也让我重新认识到算法岗的核心竞争力从来不是会多少种奇技淫巧而是面对一个陌生问题时能不能快速拆解出它的本质选对工具然后把细节做对。这个能力不是靠考前突击能获得的靠的是日常一道题一道题磨出来的积累。如果你正在准备类似的笔试我的建议很简单基础题反复过高频题认真练边界条件多想想复盘一定要做透。方法听起来平平无奇但真的能让你在笔试考场上比别人多拿不少分。
返回列表