ARTICLE DETAIL

资讯详情

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

小米算法笔试A卷考点拆解:KMP、动态规划与机器学习全覆盖

小米算法笔试A卷考点拆解:KMP、动态规划与机器学习全覆盖 说真的每次后台有同学来问“小米算法笔试到底考什么”我就想起自己2019年秋招时做那套A卷的情景。当时卷子发下来我第一反应是考得真杂。数据结构、字符串匹配、排序、动态规划、机器学习概念最后一个编程题还得现场手写代码几乎把算法岗笔试里能拿出来遛的考点都过了一遍。这套题适合谁看两类人。第一类是正在准备秋招的应届生想了解头部互联网公司算法岗笔试的题目风格和知识边界第二类是工作了几年、打算转行做算法或AI的朋友想快速摸底自己的基础够不够硬。当然如果你是靠刷题准备面试的老手那这份拆解也可以当查漏补缺的提纲。我要先说清楚我不保证能把2019年A卷的每一道题都一字不差背出来毕竟过去挺多年了但题目考的知识点、难度梯度和出题偏好我记得非常牢。下面这份拆解是按题型和解题思路来的尽量还原成可以直接照着备考的经验笔记。1. 先拆卷面小米算法笔试A卷的结构与题型分布1.1 选择题的覆盖面从排序复杂度到KMP的next数组A卷的选择题大概占了整张卷子的一半以上覆盖范围一眼看去没有明确边界。数学、数据结构、机器学习、深度学习都有涉及少数题甚至带点脑筋急转弯的性质比如给你一个情景让你判断该用哪种算法思路。我当时印象最深的一道题是直接给了模式串pabacaba要求写出它的next数组。这就是典型的KMP考法不让你写完整代码而是考你有没有真正理解next数组的计算过程。这种题会的人三十秒心算完毕不会的人连题目在问什么都看不懂区分度极高。除了KMP选择题还密集考了这几类排序算法的稳定性和时间复杂度。比如“快速排序在什么情况下退化为O(n²)”“堆排序为什么不稳定”“归并排序的空间复杂度是多少”。数据结构的操作代价。比如链表插入删除的时间复杂度、数组和链表在随机访问上的区别、栈和队列的应用场景。图算法的基础理解。比如Dijkstra能不能处理负权边、拓扑排序的适用条件。机器学习的基础概念。比如L1和L2正则化的区别、过拟合的解决办法、决策树的划分依据。这些内容看起来零散但都有一个共同点全是教科书和经典网课里反复强调的核心概念没有冷门偏题。也就是说只要把《数据结构》和《统计学习方法》两本书吃透选择题的底子是稳的。1.2 编程题的层次递进基础、中等、进阶编程题那部分我记得是三道题难度明显有阶梯。第一道偏基础类似字符串反转、链表反转、括号匹配这类热身题第二道开始上强度会跟动态规划或贪心挂钩第三道进阶题更像是在考察工程思维和边界情况的处理能力。基础题看起来简单但恰恰是失分重灾区。原因很直接在线笔试的环境里很多人一上来就急着写核心逻辑忽略了输入输出的边界处理。比如第一道字符串题题目可能要求输入包含空格的一整行很多同学用cin s去读结果只能读到空格前的部分后面怎么调试都不对。这种错误不是不会写而是没养成先确认数据范围的习惯。中等和进阶题则更看重思路的完整性。你不需要写出最优解才能拿满分但至少要保证算法复杂度是在合理范围内的暴力解能过小数据优化解才能过大样本。小米笔试的判题机制和牛客网、LeetCode类似有部分通过率的概念所以哪怕只过了部分用例也比最后一秒还在改bug强得多。2. 字符串与数据结构KMP的next数组手算攻略2.1 一个具体例子模式串abacaba的next数组KMP在算法岗笔试里出现频率不低但几乎不会让你从头到尾默写整个KMP匹配函数更多是考你next数组的计算。题目通常会给一个模式串然后用“next[i]定义为模式串前i个字符组成的前缀中最长相等前后缀的长度”这种约定。以pabacaba为例我们按字符位置从1开始编号位置i字符前i个字符组成的串最长相等前后缀长度next[i]1aa002bab003aaba1前缀a后缀a14cabac005aabaca1前缀a后缀a16babacab2前缀ab后缀ab27aabacaba3前缀aba后缀aba3所以结果是next [0, 0, 1, 0, 1, 2, 3]。这个计算过程看起来简单但有三个容易出错的地方。第一最长相等前后缀不能是字符串本身也就是说要小于当前长度第二要求是“前后缀相等”不是“前缀等于后缀中的任意子串”必须从开头和结尾同时取相同长度来比第三很多教材用next[0] -1的约定如果你习惯了另一种写法考试时一定要先看题目是怎么定义的别把一个约定下的结果直接搬过去。2.2 手算next数组的实操技巧手算next数组如果每次都从头比较很容易算到一半就乱。我自己的习惯是先写出每个前缀子串再用“看开头和结尾”的方式快速判断。比如算到第6个位置abacab先看最长的可能长度5也就是前缀abaca和后缀bacab明显不相等再看4前缀abac后缀acab还是不行一直往下试到2发现前缀ab和后缀ab相等那next[6]就是2。不用把所有可能都写出来从大到小试就行试到第一个相等的长度就停。如果题目给的是基于0的索引要求你写next数组的下标也是从0开始那就需要做一次下标转换。很多人在这一步栽跟头不是不懂KMP而是被索引搞晕了。我的建议是拿到题目先扫一眼定义的公式确认是基于1还是基于0再在旁边用铅笔标一个示例串验证一下确认无误后再快速计算全部。2.3 字符串题的其他高频考法除了KMP字符串相关的选择题和编程题还经常考这几类判断两个字符串是否互为变形词本质上是在考哈希表或计数数组。最长回文子串可以用中心扩展法也可以用马拉车算法优化的思路。字符串转整数考的是溢出判断和非法字符处理。多重字符串匹配问题引入Trie树和AC自动机的概念题。这些题的共同特点是看起来很基础但真写起来暗坑很多。字符串转整数那道题我在不同公司的笔试里遇到过至少三次每次都有边界情况没考虑到。比如正负号、中间出现空格、溢出到int范围之外这些都是评分用例里重点覆盖的边界。3. 排序算法与复杂度选择题必拿分区域3.1 一张表记住排序算法核心特性小米笔试选择题里排序算法几乎必考。最大概率出现的问法就是某个排序算法的平均时间复杂度、最坏时间复杂度、空间复杂度以及是否稳定。一张表就能解决排序算法平均时间复杂度最坏时间复杂度空间复杂度稳定性冒泡排序O(n²)O(n²)O(1)稳定选择排序O(n²)O(n²)O(1)不稳定插入排序O(n²)O(n²)O(1)稳定希尔排序O(n^1.3~1.5)O(n²)O(1)不稳定归并排序O(nlogn)O(nlogn)O(n)稳定快速排序O(nlogn)O(n²)O(logn)~O(n)不稳定堆排序O(nlogn)O(nlogn)O(1)不稳定计数排序O(nk)O(nk)O(k)稳定基数排序O(d(nk))O(d(nk))O(nk)稳定这张表不需要死记硬背关键是理解为什么。比如选择排序为什么不稳定因为选择排序会在每一轮把最小的元素交换到前面这个交换过程可能把原本靠前的相同元素换到后面去。堆排序为什么不稳定因为堆调整过程中父子节点的交换会打乱相同元素的相对顺序。3.2 快排退化问题是最常见的坑排序题里快速排序的退化问题出得特别多。快速排序在每次划分都极度不均匀时时间复杂度会退化到O(n²)。典型场景有二一个是对几乎已经有序的数组排序如果每次选第一个元素作为基准划分出来的两个子数组几乎是一边倒另一个是数组中所有元素都相同时如果基准选取不当也可能导致退化。应对方法也不难记随机选基准、三数取中或者把等于基准的元素单独分到一个区间。2019年那阵子很多公司笔试爱考“如何优化快排”这种简答式选择题本质上就是在考你知不知道这些工程化的改进手段。另外一个容易忽略的考点是归并排序的空间复杂度。很多同学知道归并排序是O(nlogn)的时间复杂度却忘了它需要一个额外的O(n)辅助数组。选择题里如果问“哪个排序算法空间复杂度最高”答案往往就是归并排序因为快排在平均情况下递归深度是logn不算太大的额外开销而归并排序不管你数据多好都得开一块等长的数组。3.3 Top K问题背后的堆排序思想编程题里有一类高频题目是Top K比如给一个无序数组找出第K大的数。最笨的办法是直接排序再取下标复杂度O(nlogn)更好的选择是维护一个大小为K的小顶堆遍历一遍数组复杂度O(nlogK)。2019年小米A卷里虽然没有完全一样的题但有一道选择题问的是“要从海量数据中找出最大的100个数最好的数据结构是什么”答案就是大小为100的小顶堆。这类题考的不是你会不会堆排序代码而是你能不能理解堆在这种场景下为什么高效它不需要对所有数据排序只维护当前见过的最大K个数省了空间也省了时间。如果笔试遇到了Top K的编程题建议直接用优先队列写完。优先队列在很多语言标准库里都有Python里是heapqC里是priority_queueJava里是PriorityQueue没必要自己从零实现堆。4. 算法思想题动态规划、贪心、二分的破局套路4.1 动态规划状态定义比递推公式更重要动态规划是算法岗笔试的常客A卷编程题第二道基本逃不脱DP。最经典的几个模型01背包、最长公共子序列、最长上升子序列、编辑距离、爬楼梯。这些题目如果之前练过考场上基本是默写如果没练过现场推状态转移方程是很痛苦的。我自己的经验是拿到DP题先别急着写代码先问三个问题状态是什么也就是用哪些维度来唯一描述问题的子问题。转移是什么也就是当前状态怎么从之前的状态计算出来。边界是什么也就是最小的子问题答案是多少。以最长公共子序列为例状态dp[i][j]表示字符串A前i个字符和字符串B前j个字符的最长公共子序列长度。转移方程是如果A[i-1] B[j-1]那么dp[i][j] dp[i-1][j-1] 1否则dp[i][j] max(dp[i-1][j], dp[i][j-1])。边界是dp[0][j] dp[i][0] 0。这套思路熟练之后大多数二维DP题都能套进去。笔试时不需要追求优化到一维数组尤其是一开始想不出滚动数组优化的人直接在原复杂度下写对拿分更实在。4.2 贪心算法证明很关键直觉会骗人贪心题在笔试里往往伪装成中等题。出题人最喜欢的方式是给一个场景让考生判断能否用贪心算法求解或者直接让考生实现贪心策略。经典的例子是会议安排问题给你一组会议的开始时间和结束时间问最多能安排多少个会议。贪心策略是按结束时间从小到大排序每次选结束时间最早且与前面不冲突的会议。这道题如果只靠直觉很容易认为应该按开始时间排或者按会议时长排但这两种策略都不对。为什么按结束时间排是对的因为结束时间越早留给后续会议的剩余时间越多。这个证明用“交换论证法”可以做假设最优解中第一个会议不是结束时间最早的会议那把它替换成结束时间最早的会议剩余区间只会变多不会变少所以长度至少不会变短。我在笔试里踩过最大的坑就是把一道动态规划题误判成了贪心题。当你能明显感觉到“局部最优不一定能推出全局最优”时就别硬上贪心及时切到DP思路。拿不准的时候先用小规模例子手推一下看看贪心选法是不是每步都对。4.3 二分查找边界条件是隐形杀手二分查找看似简单实则暗藏杀机。A卷选择题里就有一道关于“在旋转有序数组中查找目标值”的变体这种题考的不只是二分模板而是你是否清楚二分的循环不变式。最朴素的二分查找前提是数组有序。但笔试更爱考变体寻找左边界、寻找右边界、在旋转数组里查找、在值域上二分答案。每一种变体边界写法都不一样。我提供一个普适的模板思路循环条件用left right中间值用mid left (right - left) / 2来避免溢出具体判断时让left mid 1或right mid最后返回left就是答案。这个模板能覆盖大多数“找第一个满足条件的位置”的题目。注意一个细节为什么用left (right - left) / 2而不是(left right) / 2因为当left和right都很大时两者相加可能超出整数范围这在C和Java里会出现溢出Python因为整数无限大反而没事。笔试环境虽然大概率是Python或C自选但习惯写成减法做中间值是好习惯。5. 机器学习算法题不只是背概念5.1 过拟合、正则化与模型泛化的选择题小米作为硬件和AI结合很紧密的公司算法岗笔试对机器学习基础理论的重视程度不低。A卷里出现过的包括过拟合的表现和解决方法、L1与L2正则化的区别、交叉验证的作用、偏差与方差的权衡。过拟合这个概念考法一般是从表现出发训练集上loss很低测试集上表现差这叫过拟合。解决办法从数据、模型、训练策略三方面入手增加训练数据、做数据增强、降低模型复杂度、加正则化、加Dropout、提前停止训练、做交叉验证。选择题里不会让你全写出来但会给你几个选项让你挑出不正确的那一个。这里有一个高频考点常被忽略L1正则化为什么能让参数稀疏因为L1的约束区域是菱形误差等值线第一次接触到约束区域时极值点大概率出现在坐标轴上导致部分参数为0。相比之下L2的约束区域是圆接触点通常不在坐标轴上参数只会被压缩到接近0但不会是严格的0。笔试中这道题如果出成简答一定要把几何解释画出来再写文字如果出成选择看到“稀疏”两个字直接选L1就行。5.2 决策树、SVM和集成学习的考点决策树在机器学习基础题里出场率很高因为概念相对简单考试的点却很密集。你需要知道ID3用信息增益、C4.5用信息增益率、CART用基尼指数这三个算法各自选特征的标准是什么以及它们能处理连续特征还是只能处理离散特征。我有一个记忆技巧ID3的三个字母顺序和“迭代二分器”概念绑定C4.5是ID3的改进版主要改掉了多值偏好问题CART则是分类回归都能用。SVM这边常考的是核函数的作用。为什么需要核函数为了让线性不可分的数据在某个高维空间变得线性可分。常见核函数有线性核、多项式核、高斯核RBF。选择题最常问的是“当线性不可分时应该选用什么策略”答案一般是引入核函数或使用软间隔而不是简单增加特征。集成学习也是重点。Bagging的代表是随机森林核心是并行训练多个基学习器然后投票Boosting的代表是AdaBoost和GBDT核心是串行训练每个新学习器重点关注前一轮被分错的样本。如果选择题问“随机森林能降低方差还是偏差”答案是降低方差因为它通过多棵树取平均来减少模型波动。5.3 深度学习基础激活函数和反向传播深度学习在当年还是新生事物但小米笔试在深度学习上的题量已经不少了。考过的知识点包括常见激活函数的输出范围、梯度消失问题、Dropout的作用、CNN的局部感受野和权值共享、RNN的长期依赖问题。激活函数这块有个很经典的比较sigmoid输出范围是(0, 1)tanh输出范围是(-1, 1)ReLU输出范围是[0, ∞)。sigmoid有一个明显的缺陷就是在输入很大或很小时梯度接近于0导致反向传播时梯度消失。笔试中如果问“为什么深度网络不用sigmoid做隐藏层激活函数”核心答案就是梯度消失和计算开销。RNN相关的考点则是“长期依赖问题”。为什么普通RNN很难记住长时间之前的信息因为反向传播随时间展开时连续乘以小于1的梯度项会导致梯度指数级衰减。LSTM通过引入门控机制也就是输入门、遗忘门、输出门来控制信息的保留和丢弃从而缓解这个问题。你不需要在笔试里手写LSTM但至少要知道门控机制解决的是梯度消失。6. 优化算法与场景题粒子群、模拟退火考的是原理6.1 粒子群算法的核心原理解读A卷里有一个出人意料的知识点就是粒子群优化算法。当年的热搜词里成堆的“粒子群算法原理”也说明大家都在查这些东西。粒子群算法是一种基于群体智能的随机优化算法灵感来源于鸟群觅食。每个解对应一个粒子粒子在搜索空间里根据自身历史最优位置和群体历史最优位置来调整自己的速度最终收敛到较优解。核心公式就两个一个是速度更新公式一个是位置更新公式v w * v c1 * r1 * (pbest - x) c2 * r2 * (gbest - x) x x v其中w是惯性权重控制粒子保持原速度的程度c1和c2是学习因子分别控制向个体最优和全局最优学习的强度r1和r2是[0,1]之间的随机数。笔试考这种题通常不会让你写函数而是问“粒子群算法的速度更新由哪几部分组成”正确答案是惯性部分、个体认知部分和社会认知部分。再深一点会问“惯性权重w越大算法倾向于全局搜索还是局部搜索”答案是w越大粒子越容易保持原来的飞行方向越有利于全局探索w越小则更容易在当前最优附近精细搜索。6.2 模拟退火和遗传算法的对比模拟退火算法的灵感来自固体退火过程。温度高时系统接受较差解的概率大从而可以跳出局部最优温度降低后接受差解的概率逐渐变小最终收敛。核心要点是Metropolis准则如果新解比当前解好一定接受如果新解更差则以exp(-ΔE/T)的概率接受。既然接受了就可能在温度还高时越过局部最优的“山丘”。笔试如果出现模拟退火多半是考这个接受差解的概率公式以及为什么需要接受差解。遗传算法则常考选择、交叉、变异三个算子。区分这三类算法的关键记忆点粒子群和遗传算法都来自生物启发粒子群没有交叉变异用的是速度和位置更新遗传算法用染色体编码通过选择交叉变异迭代。模拟退火则跟温度这个概念绑定。这类题目不需要你刷很多题把一个算法的流程和关键公式理清楚就够了。我最担心的是同学在这个考点上花太多时间背细节反而忽略了最基础的数据结构。笔试的分数也要按性价比来分配优化算法一般只占一题结构题和机器学习基础题占了好几十分。7. 实战复盘考场上我踩过的坑和做题顺序建议7.1 时间分配不要在一道选择题上耗太久A卷题量不小我当年做的时候明显感觉时间紧张尤其是选择题部分每道题看起来都不难但都会让你犹豫几下。你要是每道题都纠结两分钟最后编程题基本没有完整思考的时间。我的建议是选择题控制在45分钟以内遇到卡壳超过2分钟的题先蒙一个然后在题目序号旁边画个问号后面有时间再回头检查。编程题每道题至少留20分钟三道题加起来一个小时左右比较理想。编程题一定要先花几分钟理清思路再动手哪怕先写出伪代码也比上来就敲代码更容易发现逻辑漏洞。7.2 高频失误输入输出格式和变量命名在线笔试的另一个大坑是输入输出格式。很多平台对空行、空格分隔、换行分隔有严格要求你写对了逻辑却输出格式不对照样判错。一个教训我记得很深有一道题要求输出多个数用空格分开末尾不能有空格我用循环打印最后一个数的时候多打了一个空格导致一个用例都没过。这种错误不是能力问题纯粹是习惯问题。写完代码后手动构造一个小用例跑一遍检查输出格式是否完全符合要求。变量命名也不要太随意。虽然笔试环境不像代码评审那样严格但变量名太混乱会在你自己调试时增加认知负担。我习惯用dp、left、right、maxVal这种语义清晰的名字避免用a、b、c、x满天飞。调试时能按直觉搜索到变量节省的时间往往比多敲几个字母多得多。7.3 复盘心得真题是最宝贵的复习素材如果你现在开始准备秋招我强烈建议把近三年小米的笔试真题都找出来刷一遍尤其是A卷和B卷都要看。真题的价值不在于原题重现而在于你能从中看出命题人对知识点的偏好和难度倾向。比如小米明显偏重机器学习基础和字符串处理对纯粹的数学证明题考察相对较少这跟另外一些公司很不一样。刷题方法上我的个人经验是“一轮分类刷二轮限时刷”。第一轮按知识点归类刷比如今天只刷KMP和字符串明天只刷DP和贪心目的是建立知识体系第二轮严格按照考试时长做整套卷子训练时间分配和临场心态。千万不要只刷自己擅长的题算法岗笔试的覆盖范围太广了弱项拖着不补考场上一定会出现在你最不熟的那个知识点上。最后再分享一个小技巧笔试前20分钟别背题也别看新题就看一眼自己整理的易错点清单。比如我自己的清单上写着排序稳定性表、KMP next数组的定义方式、二分循环条件、快排退化场景、L1和L2的区别、粒子群速度公式。这些东西虽然短但都是选择题里最常出、也最容易忽然短路的知识点。看完这些再进考场比临时抱佛脚背几道题有效得多。
返回列表