马上面试,算法怎么抱佛脚
Posted 纵横千里,捭阖四方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了马上面试,算法怎么抱佛脚相关的知识,希望对你有一定的参考价值。
我一直都反对要面试了才想起来要准备算法,临时抱佛脚很难有理想的效果。但是这又是很多人不得不面对的问题,那只有几天的情况下该怎么准备算法呢?
我上一篇文章将算法常见问题整理了一个相对完整的体系结构,然而要掌握整个体系没有几个月搞不定。如果只有几天的话, 我们只能将最重要、最频繁、不是很难的问题先搞清楚,面试能否过就全靠运气了。下面我整理了几条脉络,你可以一条条的练习:
1.一维数组
- 写个在有序数组中插入和删除元素的方法,操作数组的最前、最后和中间位置的元素都能通过,这两个方法就是用来热身的,同时感受一下如何准确操作数据的指针。
- 写一个将两个有序数组合并的方法,这个算法出现还挺频繁的。一定要手写一下。
- 掌握使用双指针解决典型的数组问题,这个思想并不难,可以用比较短的时间掌握,典型题目:元素删除相关的:LeetCode27、LeetCode80、奇偶移动相关的例如LeetCode905.等等
2.二维数组
二维数组的题目比较烦,主要是边界等问题处理起来非常麻烦 ,即使训练了,可能仍然写不出来。如果要练习的话, 可以做这几个题:
- LeetCode118 杨辉三角
- LeetCode54 螺旋矩阵
- LeetCode48 数组90度旋转
3.链表
链表算法非常重要,但是常见题目是非常固定的 ,因此是最值得提前练习的问题。突击训练的话,可以练习这几道:
- 基础题:剑指offer52 两个链表的公共子节点、剑指offer27 判断链表是否回文、如何合并两个有序链表。
- 链表的双指针问题:寻找链表的中间结点、倒数第K个结点、LeetCode141链表中是否存在环。
- 链表反转问题:链表反转是最重要、最热门的算法问题。一定要搞清楚怎么对链表进行原地反转;之后训练一下如何对链表的某个区间进行反转,以及如何K个一组进行反转(LeetCode)。
这几个问题搞清楚,链表基本就没什么问题了。
4.队栈和Hash
这部分的第一个重点是要理解这几种结构是怎么构建的,例如,如何使用数组和链表来分别构建队队列和栈,会有什么问题;Hash是如何构建的,如何解决冲突的, 很容易作为设计题来考察。
栈可以练习的题目有:
-
Leetcode20 有效的括号
-
LeetCode227 计算器
队列一般和树的层次遍历一起考察,不必单独练习。
Hash的问题比较散,一般都能想到怎么做,也不必单独练习。
5.树
树的内容特别多,而且很多并没有想象中那么难,而且常见的题目也非常固定的,因此也非常值得练习。常见问题有:
- 层次遍历问题:一定要搞清楚如何将不同的层次分开打印(LeetCode102),这个问题理解之后可以非常轻松的处理LeetCode107、103、429、515、637、199这些题。
- 前序和后序问题:核心是如何写递归方法了,常见问题包括深度和高度和相关问题(LeetCode104最大深度、LeetCode110是否平衡,LeetCode111最小深度)、对称和反转相关问题(Leetcode100两个树是否相同、617合并两个树、101是否镜像对称、226二叉树翻转)。另外还有路径搜索、公共父节点等问题,难度比较大,时间不够就放弃吧。
- 中序与搜索树问题,这个问题与二分搜索非常类似了,只不过是从树的角度考察这个问题,常见的问题有LeetCode700二叉搜索树种查找、LeetCode98验证二叉搜索树、LeetCode108将有序数组转换成二叉搜索树,至于序列化等问题就听天由命了。
- 堆和优先级问题,这个问题必须先理解堆的构建原理,而常见的题目也非常固定的LeetCode215 数组寻找第K大,LeetCode703流数据中寻找第k大,以及如何使用堆进行排序。这几个问题的好处是只要能说清楚思路就行,是否写出代码影响不大,但是必须对堆的原理非常清楚,否则会将自己绕晕。
6.查找排序
查找最重要的就是二分查找。因此二分的递归和非递归写法一定要熟练到能背下来。之后再思考一下如何元素中有重复该怎么做。
排序最重要的是归并排序和快速排序。归并就是两个数组合并+二叉树的后序遍历,而快速排序就是数组上到对撞型双指针+二叉树的前序遍历。这两个算法必须会写。
快速排序有个经典问题是如何在有序数组中寻找第K大的问题。出现频率特别!特别!特别高。
7.字符串
字符串的问题很多都可以先转换成字符数组,利用数组相关的方法处理完之后再转换成字符串,例如LeetCode709 转换成小写字母。
这里特别注意几个问题:LeetCode8,字符串转换成整数,这个题目不在于题目多么难,而是处理各类边界情况的能力,你将题目要求和示例中提供的场景记清楚就行了。
另外就是一个相对常规,看看就能会的问题:反转相关:LeetCode344、541、917、151、557这些问题。以及125回文串问题、旋转问题剑指offer58.
字符串有个很经典的子串匹配问题,例如KMP等等,这个问题是有争议的,不必看。有的人觉得是最有挑战的问题,算法里只讲KMP,还有的人觉得这么复杂的算法如果不提前练习不可能现场想出来的,因此考察没有意义。所以时间不够就不必管了。
8.滑动窗口问题
滑动窗口是数组双指针的拓展,题目还是有些难度的,练习这几个就够了:
LeetCode643 子数组最大平均数、LeetCode674 最长连续递增序列、LeetCode75 荷兰过期问题、LeetCode239滑动窗口最大值。
另外LeetCode 中还有一个累加和的问题,使用的技术可能并不一样,主要题目是LeetCode1、15、16、18、167、170、259、445、454、653这几个题目。
9.递归问题
递归问题可以很简单,也可以非常复杂,重点练习剑指offer10 青蛙跳台阶,斐波那契数列和LeetCode62机器人路径就行了。
10 贪心问题
贪心算法其实是比较简单的,也没固定模板,你也不必想什么是贪心,直接按照自己的思路想出来怎么做,然后用代码实现了就行。leetCode 55跳跃游戏是出现最频繁的问题。此外常见的题目:LeetCode455分发饼干、LeetCode860柠檬水找0、LeetCode435无重叠区间等等。
11 回溯和动态规划
如果时间不够,我建议你放弃回溯和动态规划。这两个都是递归的进一步拓展。回溯是用来解决一些暴力搜索也无法解决的问题,非常适合组合排序、子集分割、棋盘等问题。而且其算法有非常清晰的模板,但是要花很多时间来思考这个模板的含义以及如何解决问题。
动态规划也是递归的拓展,主要基于数组等实现记忆化搜索,想明白很不容易,而且难题也很多。
所以面试前将上面说的问题都整清楚,遇到回溯和动态规划就尽力而为,换了工作再来学吧。
如果你觉得我写的对你有用,就加个关注吧!
以上是关于马上面试,算法怎么抱佛脚的主要内容,如果未能解决你的问题,请参考以下文章
Android面试抱佛脚:进程间通讯学习,从Binder使用看起