关注、星标下方公众号,和你一起成长
作者 | 梁唐

出品 | 公众号:Coder梁(ID:Coder_LT
大家好,我是梁唐。
最近几次送书的活动都是算法相关的书籍,反响很不错。大家看算法学算法,本质还是为了给面试做准备,找一份不错的工作。所以今天就和大家聊聊大公司的面试环节经常涉及的算法题类型以及准备策略。

问题难度

首先大家比较关心的就是面试时候出现的算法题的难度,从我的个人经验来看,除了有一次和同样有acm获奖经历的面试官切磋了一次之外,基本上难度都没有超过LeetCode的困难难度。并且这还是因为我有acm经历加成的情况下,大部分问题都只有LeetCode Medium的难度。
当然LeetCode的中等难度这个范围也是比较宽的,既有非常简单无聊的水题,也有比较棘手,值得深入思考的高价值问题。所以只是知道这一点一点用也没有,想要知道对自己来说究竟有多难,还是需要自己亲身体会一下。
但可以非常肯定地说,LeetCode中Medium难度下的问题所用到的算法,基本上都在大学算法课程的内容里。几乎没有超纲的内容,也不涉及比较复杂和困难的数据结构,都是非常非常基础的,甚至都远远达不到高中信息竞赛的水平。我一点没和大家夸张,下面这张图是我网盘里当年高中竞赛的课件,大家可以感受一下难度。
但是算法这个东西,大家千万不要被吓到,主要是心理上唬人,实际的难度并没有那么大。真正下定决心去练习,从入门到精通也不过是几个月的事情。我当年好几个队友都是大学才开始编程,短短半年时间已经在赛场上独当一面了。

常见的题型

面试或者白板编程,由于形式的限制,题目的选择范围其实并不大。并不难理解,毕竟面试的时间有限,也不能全拿来做题,而太困难太复杂的问题候选人一点思路也没有,大部分人都做不上来,也完全起不到考察和筛选的意义。
所以拿来当做面试和白板编程的问题,不会很复杂,至少会保证绝大多数的候选人都听说过。就好像打游戏一样,哪怕是玩家津津乐道的魂游戏,总要有过关的可能。如果上来就考察一个问题,结果你连正解用到的算法都没听说过,一开始就没有做出来的可能,这种问题问了就只能浪费时间。
根据我的经验,面试当中常问的问题基本上就这几种:二分、递归、分治、排序、动态规划
这几种算法只要是科班出身,基本上都或多或少听说过,理论上来说都应该能做出来。并且这些算法除了比较基础之外,它们的代码量都不大,一般核心代码都不会超过30行,确保编码的时间不会太长。第二是比较考验思维,通过你对这几个算法的理解深度,就足以看出来你的思维能力和算法能力了。

解题套路

划好了重点,再分享几个解题的套路。

缩小问题规模

有可能问题里问的是一个规模很大的问题,比如汉诺塔问题,要移动64个圆盘,这太复杂了,我们根本无法思考。不妨把问题的规模缩小,比如缩小到3个圆盘,然后我们就可以列举一下情况,找找规律和套路了。
即使是在acm赛场当中,这个方法也非常管用。

确定复杂度

在acm赛场上题目当中都会标明数据的大小范围,除了起到限制作用之外也是一个很大的提示。我们可以根据数据的规模反推出正解的复杂度范围,从而排除掉一些不可能的算法。
比如说要在个数当中寻找某个数,由于计算机每秒的运行次数在这个量级,这么大的规模遍历一遍都有些扛不住,那么显然正解的复杂度一定在及以下。这么一来,我们就可以根据算法的复杂度排除掉一大批达不到要求的算法,排除错误的选项。
在面试的时候面试官往往不会明确给出数据的规模,我们可以自己结合实际情况分析,当然直接提问也是一个不错的选择。

优化思路

面试不是比赛,并不是一定要给出正解。有的时候,我们一时陷入误区没想到解法也是常有的。重要的并不是我们是否想出了解法,而是我们能否展现我们思维的能力,打动面试官。
所以有的时候一下子没有想到最优解也没有关系,我们可以先易后难,先把一些简单可行的解法说出来,然后再进行优化。
比如LeetCode第4题,寻找两个有序数组的中位数。我们当然很难一下子想出的正解,但是我们可以先从最简单的方法说起。比如重新排序直接寻找,这样操作的复杂度是。说出这个方法之后,我们接着从不使用排序解决问题的角度继续思考,如此一步步逐渐深入,即使最终没能找到正解,也体现出了我们的思考是有章法的,并且思考和分析问题的能力是有的。

建议

最后给大家分享几点我个人的小建议,帮助大家少走点弯路。

贵精不贵多

如果是为了准备面试,就像我前面列举的一样,其实并不会涉及很多内容。相比去研究很多高大上面试的时候用不到的高大上算法,倒不如好好把这几个算法啃扎实。
就拿排序来说,想要全部搞明白就很不简单。我随便写几个问题,大家不妨对照一下看看能不能回答上来。
冒泡排序和选择排序有什么区别?
为什么说快速排序和归并排序都基于分治算法,但它们的最差复杂度不同?
排序的稳定性是什么?哪些算法是稳定的,哪些不是?
关于快速排序算法的最差复杂度,有哪些优化?
如果都能不仅仅满足原理,而是可以深入到细节的方方面面去钻研,那么即使只是准备了几个算法,应付一般的面试都不在话下。

成体系化训练

算法的学习过程是比较痛苦的,尤其是如果我们漫无目的地去训练和学习,进展非常缓慢,非常劝退。很多同学都有刷题刷了一堆,但是水平好像没什么提升的情况。
我个人感觉比较有效的方法是成体系化的训练,不要按照题目顺序刷题,而是以算法划分专题,按照专题刷题。一个算法一个算法的硬啃,一个算法吃透再吃下一个。这样训练下来印象会非常深刻,对于算法的理解也会深刻得多,也不容易忘记。要比题目刷了一堆, 算法也用了一堆, 看起用得多,但也忘得多要好得多。
篇幅有限,今天就和大家聊到这里,感谢阅读和支持。

喜欢本文的话不要忘记三连~
继续阅读
阅读原文