写于LeetCode刷完900题之际的感想

时光匆匆,距离开始写博客转瞬便是大半年已过, 从最初寒假每天十题的刷题狂热信徒,到如今一周也做不到二十题的佛系上岸选手,有了很多感想经验,因而有了这篇文章。

 

我的第一轮刷题,始于二叉树,接着按照二叉搜索树, 哈希表,栈, 堆,优先级队列,贪心, 数组,链表, 二分查找, 字符串, DFS, 回溯, BFS, 字典树, 并查集,动态规划这样的顺序, 在同一个Tag内按由易到难的顺序做题(hard不做)同时每周坚持参加周赛,一共刷了大概600题。

我的第二轮刷题,则是从Two Sum 开始, 一路顺序往下推,比较难的hard会直接跳过,推到了300左右。

 

要问最大的感想是啥,那应该是:1. 刻意练习真的有奇效。

我刚开始的水平大概是0.3基础,不能说对CS一窍不通,但也没感觉自己正式入了门。ECE专业毕业,没上过算法课,两年前上过数据结构课,学过数组, 链表, 堆, 栈, DFS, BFS, 二叉树的概念(我读的三百本大学只教背书),编程语言只会C,还两年没写过代码, 排序算法只会写桶和冒泡, 没做过Project。简而言之就是辣鸡中的辣鸡,废物中的废物。一开始刷题基本是懵逼状态,前200题都停留在先听老师讲,然后抄答案, 再自己敲一遍,最后写博客总结的阶段。

当然该不会的还是不会,什么状态压缩DP, 线段树,红黑树, 马拉车, KMP, 树状数组,依然停留在懵逼阶段。不过也学会了一些简单的新的数据结构和算法, Sliding WIndow, 二分试探, 找素数的厄XXX筛法, 判断回文子串的中心扩散, 多状态转换的有限状态机, 给有向图存在依赖关系节点排序的拓扑排序,最小生成树。

题刷的多了之后,融会贯通,然后对数据结构和算法的理解会愈发深刻。对于此点, 我印象最深刻的一道题是 LeetCode-Python-1135. 最低成本联通所有城市, 当时打周赛还不会最小生成树,但我硬是靠理解用并查集 + 贪心 解了出来,赛后讨论才发现卧槽我写的这他🐎原来就是MST的kruskal算法,我现在咋这🐂🍺呢……

 

其次的感想就是:2. 做了,即便只做一点点,也比不做要好。

一般来说,每个人都很忙,不论是忙于学业,还是忙于生计,甚至是忙于生活中鸡毛蒜皮的琐事, 因而没有太多的时间刷题。但是刷题是门手艺活,几天不刷,稳定手生,所以我建议最好每天都能刷一会,想不出来也没关系,抄答案能学到东西也比啥都不干强。

 

再其次就是:3. 一天做10题的收获  > 十天做10题。

我听说过一个理论,叫做MAD,全称是 Many Actions Day,意为在同一天做很多件相同的事来练习。我实践之后的体验也是,确实一天做10题能学到的东西远大于十天做10题。特别是如果一天能刷10道相同的tag的题,比如链表或者二叉树或者回溯, 收获真的是巨大。 我觉得这像是在用训练神经网络的方法训练人类大脑,喂一堆训练集进去,然后脑子就可以逐渐适应并理解正确的思路,下一次碰到类似的题也可以快速有思路写模版出来。

 

4. 保持心情愉快。

对于大多数人来说,刷题很难,很枯燥,特别是在初期。如果你感觉还没有跨过入门的门槛(对我而言,这个门槛是200题~300题),那么我建议不要在一道题上纠结过长的时间(我也不推荐入门前做Hard),而是坦率承认自己的不足。大家都不是宁缺(没看过《将夜》的朋友可以跳过这一句),人非生而知之者,哪有人一开始就会刷题的呢?那些OI 或者 ACM出身的大佬,也得是接受了专业且系统的培训,又在OJ上刷烂了不知道多少题,还有丰富的竞赛经验,才有了今天的虐菜手速和思路。

不会做题也没什么关系,千万不要着急,碰到不会做的题,抄抄答案,看看题解,自己再写点分析放在评论区,也能有所收获。我倒是觉得三分钟就能AC的题完全没有价值,能让我找到自己不足点的题目,才是好题。

心情不好的时候,看看直播,看看小白网文, 和朋友聊聊天,打几把LOL,看几个网课视频,都是不错的放松方法。等到心情好了,不再烦躁了,也不丧了,再刷题,事半功倍。如果天天抱怨“我怎么这么菜,这垃圾题我都不会做”,这种心态一定会影响刷题的状态。

 

另外,5. 多和别人交流 and Think out loud。

刷题的真理是这样的:你会一种方法,别人也会一种方法,你们交流一下,就变成了两个人都会两种方法。而且面试的时候,大忌之一就是埋头写码,正确的做法是一边写,一边用嘴说分析思路,最好能把面试当成给面试官上课讲题。这平时咋练呢?答案是:在网站上和别人留言交流,现实里约人互相Mock Interview。另外推荐一个免费的online mock 网站,pramp,可以和朋友一起mock,也可以随机匹配网友互相mock。

 

以及,6. 人生苦短,我用Python。

Python在刷题和面试这一方面,对比其他的语言来说,简直是降维打击般的存在。

  1. 代码简洁,无论是刷题在键盘上打代码,还是面试当场在白板上,或者在白纸上写,整体代码的长度都会相较而言短很多,因此有更多的时间思考。同时,简洁的代码量也易于思路清晰 和 Debug。 我最近在地里看一老哥用C++给面试官跑Test Case之后,抱怨C++输出相较Python太不方便。Python选手反手一个 print ()的事,他得敲一整行 cin cout 出来……
  2. 自带的库多,比如我酷爱的Counter和 数组字符串切片。在体验了C语言处理字符串的SB程度后,我写点Python都能享受到精神高潮的快感。

 

当然,Python不是没有缺点:

Python 速度太慢了。在网站上做题时,相同的思路,有可能C++可以过,但是Python就不行……(我见过最夸张的是一场周赛的第四题,一道求三个绝对值之和数学题,暴力的方法除了Swift还是JavaScript之外全部暴毙)所以我推荐再学个Java(虽然我说了半年要学61B,现在还是没学完hhh),网站上做题如果Py不行就切Java。不过这一点在面试时,不会体现出来。

 

再来,7. 推荐参加周赛。

我碰到很多人都说,他们觉得自己特别菜,一题都做不出来,所以不愿意打周赛。我觉得这种心态不对。

首先,周赛是免费的,并不需要买票才能打。因此花费的只是时间成本。

其次,周赛出的都是最近的面试高频题,比如亚麻的OA题 零件合并(这题感觉出了两次) + Critical Connections,可以很好地反映最近的题目趋势。又比如 1231.分享巧克力,这个是新鲜的🐶家面试题,类似包装的题还有410 875 1011 1201, 都是可以读完题确定答案必定落在某个区间[left, right],然后二分法不断缩小区间,找到最终正确答案。

而且,打周赛可以赚积分,积分可以换一系列力扣的周边,比如鼠标垫,帽子,T恤,卫衣,钥匙串,可擦笔,都是很有纪念价值的礼品。

同时随着LeetCode积分的逐渐水化(现在连同时参加周赛和双周赛都有加分了, 国区66, 美服100,所以一个月保底330分是稳稳滴;国区还有题解首发一篇55, 精选题解一篇220的额外奖励), 拿到T恤或大礼包也不再是难事。我在七月底就拿到了自己的第一件T恤,同时因为在 leetcode-cn.com 上写了很多题解,所以被运营姐姐赠送了价值800积分的 定制可擦笔 + 钥匙串 + 贴纸 的大礼包。八月九月又打了4500分出来……所以说积分真滴越来越好拿。

 

最后, 8. 打好基础吧,

基础很重要, 特别是像我这种转行没学过算法的,

这不仅体现在面试写题,你得分析一通时间空间复杂度,

也体现在对题型对应哪些数据结构和算法的敏感度上。

就像我现在:

看到 数组有序,就是二分,

问组合 + 数据size < 20 ,就是回溯,

问括号, 就是栈,

问图里的点的联通,就是UFS(DFS, BFS也可以,但是我超级喜欢UFS),

问有向图的依赖关系, 就是拓扑排序,

问最短距离,就是BFS,

问链表或者二叉树,递归或者迭代走起,

问TOPK, 就是堆,

题目暗示答案存在的可能区间,二分试探冲冲冲,

---------------------------------------

刷了200题之后,我买了极客时间(此处不是广告,只是自来水,你们想买啥课都行)上的网课补基础,感觉提升巨大。

这个课带着我复习了一堆数据结构的时间复杂度,也学了很多新的数据结构和算法,比如并查集就是在这学的,老师用找帮派老大的例子形容并查集, 搞得我印象深刻,之后周赛打到UFS都能非常快地判断题型,然后给出解答。

 

最近开学了,学校的生活过于充实,导致我抽不出太多的时间刷题,所以博客更新频率也有所降低,请多多见谅。另外下一步刷题的计划应该是复习前300题和后两200题,做面经题,以及再修订之前写的题解和尽量给每种题解增添新的时空复杂度分析。

 

很久没写过中文的文章了,如果言不达意,亦或不够通顺,还望海涵。另外本人是CS民科出身,自知基础水平薄弱,如果题解或者分析出现错误,请直接指出,感激不尽!

 

初稿写于2019年09月30日 飞行途中。

二稿修于2019年10月31日 万圣节之夜。

三稿修于2019年11月6日 一个不想写33作业之夜

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页