仅以本文总结搞定算法面试的方法和如何使用Leetcode刷题方法,记录自己的想法也能帮助到有需要的同学。
为什么要学习算法
在了解如何学习算法和有效刷题之前首先思考一分钟学习算法和刷题的目的。
最简单的原因是软件工程师工作面试会考察面试者能否写出给定问题的解决方案。更重要的是算法作为对复杂问题的抽象是计算机科学很重要的一部分。只有数量掌握了算法和数据结构,才能写出更好的代码。比如我最近在学习UC Berkely 的CS 186时需要实现B+ Tree,因为有了算法的基础,很快就能写出代码。记得mit 算法课程上说要成为一个好的coder的方法是每天写代码,并学习算法这门课。
本文主要针对如何解决面试中的算法题,至于算法内功心法部分有机会会在其他文章中记录。
分类刷题
Leetcode题目有两种分类方法,一是按照算法和数据结构类型分类,二是按照不同公司题目出现频率分类。如果是基础比较薄弱的同学,推荐先攻克不同类别的题目,在有一定基础之后可以去刷心仪公司的高频题。高频题其实只是有一定的参考价值,如果能够很好掌握每种类型的题目,则不论面试哪一家公司都会有很好的表现,所以不刷高频题也是可以的。
根据算法和数据结构类型,可以分为这些主题:数组,链表(相关的指针操作,如双指针),二分查找,栈,队列,优先队列,二叉树(先序遍历,中序遍历,后序遍历,迭代方法,循环方法),图(BFS,DFS,拓扑排序),Trie,回溯,动态规划等。
在学习数据结构和算法之前,需要先掌握算法的时间复杂度和空间复杂度,具体来说就是O标记。只有掌握了时间复杂度才会知道每种数据结构和算法的优势是什么,结合数据结构和算法的特点才能在解决问题时选择正确的数据结构。
解题顺序
在了解了以什么顺序进行进行学习之后,下面说明一下针对一道题目的解决思路。
- 先了解暴力求解方法再进行优化。如果连暴力求解方法也不知道,可能对于题目本身是没有理解的。
- 没有思路怎么办?
- 看题目的解答和讨论区学习解法
- 为什么会没有思路呢?一个原因可能是这个题目用到了你不知道的数据结构,例如如果你没有听过Trie,那么自然不会解决使用Trie的题目了。另一种是虽然知道大概方向但是不能真正写出代码,这就需要多加练习啦
- talk is cheap, show me the code.
- 知易行难,在知道链表和真的写出reverse一个链表之前还有这很长的距离,对于每一道练习的题目一定要落实到代码上。
- 对于不会的题目即使是在理解了思路后抄一遍答案,以后回顾的时候在写一遍也是有价值的。
- 先有思路再编码。
- 想清楚edge case
- 回顾题目。对于解决的题目要有意识的进行回顾,尤其是没有一次达到bug free,卡在思路和边界条件上的题目。可以在学习完一个主题之后集中回顾。回顾时也要落实到代码。