1.常看Discussion。我相信很多同学为了刷题量,解开一道题后会迫不及待地点开下一道题。更为甚者,很多同学把刷题的数量作为衡量水平的绝对标准,比如“老师,我在Leetcode刷了500题,您看去面Google有希望吗?”,结果该挂还是挂了。但是,你有没有试过思考其他过解决方案? 这里并不只是说在自己的代码上继续优化,而是点开Discussion, 看看其他人有没有其他的思路,并思考他们的解法和你的有什么不同。也就是说,Discussion也是刷题的一部分。同学们往后可以注意这点,注意分析别人的思路,并确保你至少理解其中的一到两种。
2.给自己计时。练习某一类型的题目时,一开始给自己定1小时时间,解不出来就去看Solution,一开始即使做不出来也不用气馁,只要下一次遇到同类型的题目,自己的思路比上一次更进深入,就是进步了。一开始慢一点没关系,只要坚持下去就好。 从一开始有自己的思路,靠参考Solution写出代码。到看到同类题目时就有明确的思路,知道最佳的解法。再到最后看到一道题时就知道它的考察点,能短时间内写出代码。
3.针对自己的弱点。做那些你未曾涉足的题型,比反复练习你已经熟知的题型更能扩充你的知识储备。千万不要害怕做不出来,要敢于走出舒适区。Leetcode上有14天的各类题型专业训练,从简单到难,还包括各类题目的原型和变种。可以通过这个专栏来扩充自己的题池。
4.按照正确的顺序刷题。推荐优先刷的题目有:
热题HOT 100和面试精选题;
题号靠前和Frequency高的题;
刷哈希表,二分,二叉树,链表,DFS等常见考点的题;
刷Easy和Medium难度的题足以应付大部分Entry Level的面试了,Hard难度的题在很少出现,而且理解起来很费时间,刷起来性价比很低。但是同学工作几年后到了Senior Level可能就要开始在这Hard问题一块侧重了。
可以把这些题作为例题,这一步的任务就是收集这些例题并熟悉他们的思路,让你以后再看到这些题的变种时能够像映射函数一样映射出解法。
5.按Tag分组定期复习。重新做之前刷过的问题,有助于掌握正确的解法。有些同学可能有过这样的经历,明明以前刷过这类题,过了一段时间再做还是不会,思路在脑子里就像蒙了一层雾一样,隐隐约约感觉知道怎么做,但就是写不出来。别担心,这是正常的学习进程。 过一段时间重新回顾后,就会加深对这个Tag的印象,从而做到举一反三。
6. 按照正确的思路刷题。很多同学刷陌生题时没有明确的思路,只是盲目地写一段代码,然后感觉不对,就把写出来的东西修修补补,写到最后自己也看不懂代码是干什么的。其实,把做一道题的流程列成步骤,就是以下几步:
第1步:思考这道题的考察点和最优解;
第2步:把自己的思路在纸上用伪代码的形式表达出来,例如:
A <- an intergar
B <- an array
C <- a nodelink
If <condition> Then
{
do
}
Elseif <condition> Then
{
do
}
Else
{
do
}
第3步:把伪代码转化成实际的代码;
第4步:根据Edge Case的实际情况Debug。
后两步是不怎么花时间的,只要你对题目有大致的思路,把它用代码表达出来就只是时间问题了,因此前两步是最重要的。同学们遇到新问题,大概率连思路也没有,此时也不要慌张,按照我们上边第2步讲过的定时法,在限制时间内优先理清思路。让你以后在看到实际问题时,能条件反射般地想出解题思路。
7.最后最重要的一点:持之以恒。俗话说一天不练琴要花三天找回手感,编程也是如此。一旦某天偷懒给自己放个假,轻则自己昨天刚记住的题马上就忘了,重则大脑可能就无法从休假模式中回过神来了!通过每天做一定量的题,定期刷某个Tag 的题,可以保持自己的手感和编程思维,久而久之才能让知识真正变成自己的东西。这个过程听起来艰难,但实际并不是这样的,万事开头难,难以坚持的只有刚开始的时候。当你持续刷题一周,两周,一个月后,每天刷题就会像呼吸一样变成一件自然的事情,也就不再是一件需要逼迫的事情了。而且刷题也并不意味着是必须把Code写出来,Bug Free的提交,今天比较忙,那么我看一道题,想一下思路,写一下伪代码,保持一下状态,也是可以的。