赞
踩
干货长文预警!!!6 千多字的干货长文,建议先点赞收藏~
先不说学算法有没有用,但我们得接受一个现实:好一点的公司都要面试算法
对于应届校招生,基本都要面临算法笔试和面试两关,每一轮技术面都会有算法题
笔试比面试要难,本文末尾,除了会告诉你如何避开笔试,也会有 2021 年各大厂校招笔试总结的链接(内含题解和代码)
对于社招,每一轮技术面都会有算法题,有的公司甚至需要算法笔试,比如华为系的公司
V2EX 上有个用户,有 8 年大数据底层开发经验,面试的时候,算法回答的不好,照样过不了
我和这个哥们的经历类似,我做了 4 年 【Java Web & 大数据开发】,然后去字节跳动面试
一开始的框架方面的知识,我是真的侃侃而谈,面试官也基本可以判断出,框架啥的是难不住我的
然后就给了我一道算法题,是现场写代码的那种,因为是第一次遇到,不习惯,我是非科班的,算法真的是我的软肋,这样,面试官看完我的代码,然后来了一句,今天就到这吧,等通知~
还有一次,在公司,我的领导问我一个问题,给你两个字符串,你怎么匹配,我当时回答的就是一个字符一个字符的匹配呗,当时我领导就说,要是我面试你的话,我是不会要你的 (ps: 我的面试不是领导面试的)
实际上,我这个时候已经遇到瓶颈了,薪资老是提不上去,结合前面的两件事,我意识到了薪资提不上去的真正原因:最基础的数据结构与算法掌握的不扎实
我这个人有一个优点,就是遇到问题解决问题,从那个时候起,开始边工作边系统学习数据结构与算法,想要系统学习算法,并不是一件很容易的事情,不断的看视频,有免费的,有付费的,不断的看书,看博客,刷题,走了很多弯路,也有迷茫的时候,但还是坚持下来了
现在的我,作为面试者面对算法,完全可以从容面对;作为面试官,我也知道为什么要出算法题,并且知道怎么考算法题,才能为公司选拔优秀的人才
接下来,我以一个过来人的身份,和大家一起梳理下,如何准备算法笔试和面试
有一个最基本的常识得记住:算法的学习相对比较难,面试的准备也不是一朝一夕的事情,更不是说你面试之前背一背就可以的,这个是需要花时间的~
先来看看,要通过算法笔试面试,你需要掌握的知识包括:
以上是我个人经验的总结,如有考虑不周的地方,大家可以在评论区写下自己的看法哟~
算法面试和笔试的准备,只需要两大步:啃基础、刷适量的题
先看一个很简单的例子
对于学算法,啃基础是一件事半功倍的事情,我们来看一个高频算法面试题:
给一个数组进行升序排列,规定: 1. 数组的长度是 1 到 50000 2. 数组中每个元素的大小是 [-50000, 50000]
一个基础扎实的同学会这么思考这个问题:
首先数组的长度最长为 50000,也就是数据规模是 5 * 10^4,那么要实现的排序算法的时间复杂度肯定不能超过或者等于 O(n^2)
然后看到每个元素的大小范围非常大,还有负数,所以用不了时间复杂度为 O(n) 的计数、基数以及桶排序,那么可以选择时间复杂度为 O(nlogn) 的快速排序或者归并排序来解决这个问题
要达到这种水平,你需要两个基础和一个经验
第一个基础就是时间复杂度分析,第二个基础就是你要明白各种基础排序算法的特点
一个经验就是:利用输入数据规模,反推你要实现算法的时间复杂度,然后根据时间复杂度选择适当的算法
一般情况下,如果数据规模在 10^4 的话,那你实现算法的最差时间复杂度是 O(n^2)
10^4 ~ 10^7,对应为 O(nlogn)
10^7 ~ 10^8,对应为 O(n)
10^8 以上,对应为 O(logn)、甚至 O(1)
你可能会问,为啥子有这种规定,我想说的是,这不是规定,而是经验而已
如果你用时间复杂度为 O(n^2) 的算法,作用在数据规模超过了 10^4 的输入数据上,那么算法执行时间太慢,导致超时(每道算法题都会有时间限制的)
由此可见时间复杂度的重要性了,时间复杂度搞懂了,你的算法知识也基本掌握了一半了,当然,除了时间复杂度,还有一个相对简单点的空间复杂度,也是很重要的~
如果你想仅凭看一两篇文章就彻底搞懂时间空间复杂度,那是在做梦。除了看文章,还需要不断的在写代码的时候,对代码的时间复杂度进行推导计算,等你代码写多了,见多了,你会自然而然的搞懂时间复杂度的
数据结构的学习有三个阶段
第一个阶段:认识数据结构的基本特点,比如我们知道栈的后进先出、队列的先进先出的特点
第二个阶段:会使用编程语言提供的内置数据结构,比如 Java 中的 Stack、Queue,C++ 中的 stack、queue 等
如果你只是停留在第二个阶段的话,你将很难理解透彻这些数据结构,进而影响你对这些数据结构的灵活运用,从而导致你很难应对稍微难一点的算法笔试或者面试
所以,你必须进入第三阶段:用你自己熟悉的编程语言,手写代码实现每一个基础且重要的数据结构,比如双链表、栈、队列、堆、哈希表等
就拿队列来说,队列是一端进一端出,也就是包含入队和出队两个操作
我们可以用数组实现,也可以选择使用单链表来实现
如果用数组来实现的话,出队需要删除数组的第一个元素,那么后面的元素都要往前挪动一个位置,所以这个时间复杂度是 O(n),这太慢了
如果使用单链表来实现的,入队需要往链表表尾插入数据,因为要从表头 head 往后一个一个找到表尾,所以这个时间复杂度仍然是 O(n),也太慢了
为了降低时间复杂度,提高性能,可以:
基于数组来实现循环队列
多用一个指针 tail 指向单向链表的表尾
这样,不管是数组,还是单向链表实现的队列,入队和出队的时间复杂度都是 O(1)
那么重点来了,用数组或者链表实现队列,具体的代码怎么写呢?如何落地呢?这就是第三个阶段需要做的事情了,这太重要了
你还需要考虑的是,什么场景下使用数组实现的队列,什么场景下使用链表实现的队列呢?
经过这么一折腾,数据结构你可以吃的透透的,什么场景选择什么数据结构,简直就是手到拈来的事情,如果将这种数据结构选择的思路,上升到架构的高度的话,可以为你做技术选型打好坚实的基础的
在啃基础阶段,你需要掌握的算法包括:排序算法、二分查找、字符串匹配算法、DFS、BFS、哈希查找、堆查找
当然,还有图论相关算法,包括 floodfill 算法、环检测、二分图、拓扑排序、最短路径、最小生成树等
对于其他的算法(比如回溯、贪心、动态规划等),请到刷题阶段学习和练习
这个阶段,你需要熟悉每种算法的思想以及实现,比如说:
几大常用的排序算法你得能用代码实现,包括冒泡排序、选择排序、插入排序、归并排序、快速排序、计数排序、基数排序、桶排序
然后适当的找一些相关的算法面试题试试水即可,不要求能熟练的应用
注意:以下举的例子,你要是不会的话,没关系的,主要是梳理准备面试的思路哈,别被下面的例子吓到,压压惊~
比如,你学完排序算法,你就可以找【颜色分类】这个高频算法题试试水:
给定一个包含红色、白色和蓝色, 一共 n 个元素的数组, 原地对它们进行排序,使得相同颜色的元素相邻, 并按照红色、白色、蓝色顺序排列
这道题目可以使用普通排序、计数排序、快排分区等多种手段解决,可以很好的练习排序算法
再比如,当你学完基本的二分查找算法,并且也熟悉了几种变形的二分查找后,你可以找【搜索插入位置】这道题来练练:
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
因为规定数组有序,所以可以使用时间复杂度为 O(logn) 的二分查找来实现
以上每道题知识考察一个知识点,而且相对简单,但在面试或者笔试中,一道题目可能要考察多个知识点,比如排序算法和二分查找一起考察,比如【最接近的三数之和】这道题:
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。
这个难度就上来了,这里需要先排序,然后再二分,而且这个二分是比较难看出来的,对于这种题目,我么需要在接下来的刷题阶段,做刻意的练习的~
到现在为止,你已经对数据结构的理解非常的透,对常用的基本算法也有一定的掌握
对于简单的面试问题,你已经可以完全应对了,但是想去大厂的话,你还得刷适量的题
这里的刷题是指:做一些非常经典的、面试中常问的算法原题
如果是几年前,你可能只需要刷 100 道左右高频算法题即可
现在的话,想通过所有算法面试的话,最好是要刷到 300~400 道左右的高频算法题了
再过几年的话,这个数量会不会再次上升呢?这个我就不确定了,你可以在评论区留下你的看法~
虽然数量在上升,但是刷题最重要的策略还是:重质量,而非数量
也就是每一道高频经典算法题要搞的滚瓜烂熟,而并不是单纯的为了数量而刷题。所谓的滚瓜烂熟就是指,对于每道经典算法题你可以做到:
从暴力法开始,一步一步的优化代码,使得代码是最优解
可以从不同的角度去思考,也就是可以做到一题多解
刷题的第二个非常重要的策略:分门别类的去刷这 300 多道题
记住,分门类别时,类别一定要全面,因为某个类别没有准备到,而与好公司插肩而过,实属可惜
类别与类别之间得按照顺序来刷,甚至一个类别中的题目与题目之间最好也是按照顺序来刷。
举个例子:我们遇到很多求第 k 大、第 k 个等 kth 问题,一般都可以通过快排分区、或者堆来实现,那么你在刷 kth 这类问题之前,是不是最好把排序算法、堆这两个类别相关的题先刷完呢
我们可以按照从简单到难的顺序,分成 5 个系列 22 个类别:
数组、字符串、整数的基本操作, 5 个类别:一维数组、二维数组、字符串、数学、位运算
经典查找算法,6 个类别:排序、二分查找、哈希查找、栈和队列辅助查找、堆查找、滑动窗口
动态数据结构,4 个类别:链表、二叉树、二叉查找树、DFS 和 BFS
数据结构设计,包括 3 个类别:缓存、并查集、字典树
高级算法,包括 4 个类别:回溯、贪心、动态规划、图论相关算法
以上,前面的类别是后面类别的基础。每个类别挑选 10 到 30 道经典的算法面试题即可,加起来,差不多 300 多道题。那么,怎么选 300 多道题呢?这 300 多题怎么分类呢?要想知道这 300 题怎么选的,可以私信我的~
如果你是刚接触算法的新手,每一道高频算法题对于你来说,都是一座很难翻越的高山,那么请你回到啃基础阶段
如果你稍微有点基础,或者说你懂点数据结构,懂点基础算法,面对每道算法题,也够你喝一壶的,比如:
太多的人在简单的 two sum 经典算法题上就会折腾很久,即使你看了题解答案,过两天,你再去做的话,你也不一定能做出来,不知道你有没有这种经历呢?
当然,这个是正常的
如果连题解答案你都看不懂的话,这个就不正常了,实际上,上面所说的 300 多道题目中,很多题目的题解答案你是看不懂的
看不懂的原因主要包括:
你所看到的题解写的太烂
触碰到了你的知识盲区,也就是题目所考的知识点你都不熟悉
所以,你需要做的就是:
跟着优秀的题解刷题
系统的刷题,这样就不会存在知识盲区了
如果你只是刷完了 300 多道题目,面试没问题了,但是笔试的话,你还需要更多的努力
你可能会遇到下面的两种状况:
碰到的笔试题不难,但是你在折腾输入输出的时候,搞得自己满头大汗,在输入输出上花了太多的时间,然后笔试过不了~
你也可能碰到笔试题描述太长,自己内心产生恐惧,进而怯场,然后就放弃了~
之所以出现上面的两种情况,有两点原因:
首先,你没有事先准备,没有事先去做一做之前的笔试真题,这个其实和你在学校考试是一个道理
其次,你存在知识盲区,你一定要清楚的一点是,不管笔试题怎么变,每道笔试题其实都是考察 1 ~ 2 个知识点的,真的是万变不离其宗的,这点一定要坚信
一般笔试题是不会无厘头的,你要是觉得它无厘头,那可能就是你的算法知识不够扎实~
你要是不信的话,你可以看下我整理的 2021 年校招笔试题(图片下有题解代码链接):
2021 年校招算法笔试题解和总结(持续更新中...)https://blog.csdn.net/spark_tang/article/details/121223092
对于笔试来说,熟悉每一种数据结构或者算法的应用场景,是非常重要的,因为很多笔试题都是场景驱动的题目~
由于算法面试的时间很短,所以面试官给你的算法面试题是很短的,他会直接告诉你给你一个数组或者给你一个链表,然后再说要解决的问题~
但是笔试算法题不会直接告诉你输入的数据结构,而是告诉你一个场景,然后需要你自己将这个场景对应的输入数据结构抽象出来滴~
我们找一道题来看一下,来看一下今年美团的校招算法题:
以下是输入示例数据,n = 4,k = 4:
4 4 1 2 2 1 2 3 2 1 4 4 4 3 2 3 2 1
对于这道题,我们不能一眼看出这个算法题输入是什么数据结构,我们需要通过不断将这个场景进行抽象:
我们可以将 n 乘以 n 的小方格抽象成 n 乘以 n 的二维数组
然后根据小美的跳方格的规则,再次从这个场景中抽象出无权有向图,如下:
上面二维数组中每个元素作为图的顶点,因为可以从一个元素的上下左右跳,所以元素与元素之间就是边,但是这里必须是有向边,因为小美只能从 1、2、....、k 依次跳
也就是说,最终我们把问题抽象成图结构了,那么解决图结构上的问题,无非就是 DFS 和 BFS 两种算法了,如果同学们在刷题的时候,刷过图结构中的 floodfill 算法相关类型题的话,这道题目就非常简单了
所以说,如果想通过算法笔试题的话,你还需要刻意的练习抽象能力,这个也可以通过在刷题或者做笔试原题的时候,刻意练习下即可。
以上就是准备笔试的时候需要多做的努力了。
其实,想去大厂的同学,是完全可以跳过笔试这个阶段的,你可以通过走提前批,提前批是不需要笔试的,但是每轮技术面,还是会有算法题的,相对难度低点
我们先看一张校招时间线图:
提前批的本意是提前网罗优质人才,是企业与企业之间的人才战,所以提前批的要求一般更高些
如果你的简历很优秀的话,可以直接参加提前批,只要简历过了,就可以直接参加面试,不需要参加算法笔试
而且,很多公司提前批挂了,还能参加正式批的校招,相当于多一次求职机会
如果提前批挂了,也不要灰心,好好准备,参加正式批,一般是需要参加笔试的,但是,需要注意的是,笔试的结果只是作为参考,如果笔试没做好的话,也是有机会进入面试阶段的
总之,加油就对了,皇天不会辜负有心人的,祝福所有的参加面试的同学,都能通过!
最后,想说明的是,不止是在面试中,数据结构与算法才有用。实际上你对数据结构与算法的掌握程度,可以直接决定你的职业高度的
所以,如果你还想接着吃软件开发这碗饭的话,数据结构与算法还是要狠狠的学透的
谢谢大家,以上!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。