上一篇文章 學習數(shù)據(jù)結(jié)構(gòu)的框架思維,我也發(fā)到了不少其他圈子,受到了大家的普遍好評,這一點我真的沒想到,十分感謝大家的認可,我會更加努力,寫通俗易懂的算法文章。有很多朋友問我數(shù)據(jù)結(jié)構(gòu)和算法到底該怎么學,尤其是很多朋友說自己是「小白」,感覺這些東西好難啊,就算看了之前的「框架思維」,也感覺自己刷題乏力,希望能聊聊我從一個非科班小白一路是怎么學過來的。 首先要給懷有這樣疑問的朋友鼓掌,因為你現(xiàn)在已經(jīng)「知道自己不知道」,重視算法而且開始嘗試學習、刷題、尋求幫助,能做到這一點本身就是及其困難的。 關(guān)于「框架性思維」,對于一個小白來說,可能暫時無法完全理解(如果你能理解,說明你水平已經(jīng)不錯啦,不是小白啦)。就像軟件工程,對于我這種沒帶過項目的人來說,感覺其內(nèi)容枯燥乏味,全是廢話,但是對于一個帶過團隊的人,就會覺得軟件工程里的每一句話都是精華。暫時不太理解沒關(guān)系,留個印象,功夫到了很快就明白了。 下面寫一寫我一路過來的一些經(jīng)驗。如果你已經(jīng)看過很多「如何高效刷題」「如何學習算法」的文章,卻還是沒有開始行動并堅持下去,本文的第五點就是寫給你的。 我覺得之所以有時候認為自己是「小白」,是由于知識某些方面的空白造成的。具體到數(shù)據(jù)結(jié)構(gòu)的學習,無非就是兩個問題搞得不太清楚:這是啥?有啥用? 舉個例子,比如說你看到了「?!惯@個名詞,老師可能會講:先進后出、函數(shù)堆棧等等關(guān)鍵詞。但是,對于初學者,這些描述屬于文學詞匯,沒有實際價值,沒有解決最基本的兩個問題。 如何回答這兩個問題呢?回答「這是啥」需要看書,回答「有啥用」需要刷題。 一、這是啥? 這個問題最容易解決,就像一層窗戶紙,你只要隨便找本書看兩天,自己動手實現(xiàn)一個「隊列」「?!怪惖臄?shù)據(jù)結(jié)構(gòu),就能捅破這層窗戶紙。 這時候你就能理解「框架思維」文章中的前半部分了:數(shù)據(jù)結(jié)構(gòu)無非就是數(shù)組、鏈表為骨架的一些特定操作而已;每個數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的功能無非增刪查改罷了。 比如說「列隊」這個數(shù)據(jù)結(jié)構(gòu),無非就是基于數(shù)組或者鏈表,實現(xiàn) enqueue 和 dequeue 兩個方法。這兩個方法就是增和刪呀,連查和改的方法都不需要。 二、有啥用? 解決這個問題,就涉及算法的設(shè)計了,是個持久戰(zhàn),需要經(jīng)常進行抽象思考,刷算法題,培養(yǎng)「計算機思維」。 之前的文章講了,算法就是對數(shù)據(jù)結(jié)構(gòu)準確而巧妙的運用。常用算法問題也就那幾大類,算法題無非就是不斷變換場景,給那幾個算法框架套上不同的皮。刷題,就是在鍛煉你的眼力,訓練你透過問題找框架。 比如說,讓你求解一個迷宮,你要把這個問題層層抽象:迷宮 -> 圖的遍歷 -> N 叉樹的遍歷 -> 二叉樹的遍歷。然后讓框架指導你寫具體的解法。 抽象問題,直擊本質(zhì),是刷題中你需要刻意培養(yǎng)的能力。 三、如何看書 直接推薦一本公認的好書,《算法第 4 版》,我一般簡寫成《算法4》。不要蜻蜓點水,這本書你能選擇性的看上 50%,基本上就達到平均水平了。別怕這本書厚,因為起碼有三分之一不用看,下面講講怎么看這本書。 看書仍然遵循遞歸的思想:自頂向下,逐步求精。 這本書知識結(jié)構(gòu)合理,講解也清楚,所以可以按順序?qū)W習。書中正文的算法代碼一定要親自敲一遍,因為這些真的是扎實的基礎(chǔ),要認真理解。不要以為自己看一遍就看懂了,不動手的話理解不了的。 但是,開頭部分的基礎(chǔ)可以酌情跳過;書中的數(shù)學證明,如不影響對算法本身的理解,完全可以跳過;章節(jié)最后的練習題,也可以全部跳過。這樣一來,這本書就薄了很多。 相信讀者現(xiàn)在已經(jīng)認可了「框架性思維」的重要性,這種看書方式也是一種框架性策略:抓大放小,著重理解整體的知識架構(gòu),而忽略證明、練習題這種細節(jié)問題,即保持自己對新知識的好奇心,避免陷入無限的細節(jié)被勸退。 當然,《算法4》到后面的內(nèi)容也比較難了,比如那幾個著名的串算法,以及正則表達式算法。這些屬于「經(jīng)典算法」,看個人接受能力吧,單說刷 LeetCode 的話,基本用不上,量力而行即可。 四、如何刷題 首先聲明一下,算法和數(shù)學水平?jīng)]關(guān)系,和編程語言也沒關(guān)系,你愛用什么語言用什么。 算法,主要是培養(yǎng)一種計算機的思維方式,所謂「計算機思維」。就跟你考駕照一樣,你以前習慣騎自行車,有一套自行車的規(guī)則和技巧,但現(xiàn)在你想開汽車,就需要適應(yīng)并練習開汽車的規(guī)則和技巧。 LeetCode 上的算法題和前面說的「經(jīng)典算法」不一樣,我們權(quán)且稱為「解悶算法」吧,因為很多題目都比較有趣,有種在做奧數(shù)題或者腦筋急轉(zhuǎn)彎的感覺。比如說,讓你用隊列實現(xiàn)一個棧,或者用棧實現(xiàn)一個隊列,以及不用加號做加法,開腦洞吧? 當然,這些問題雖然看起來無厘頭,實際生活中也用不到,但是想解決這些問題依然要靠數(shù)據(jù)結(jié)構(gòu)以及對基礎(chǔ)知識的理解,也許這就是很多公司面試都喜歡出這種「智力題」的原因。下面說幾點技巧吧。 盡量刷英文版的 LeetCode,中文版的“力扣”是閹割版,不僅很多題目沒有答案,而且連個討論區(qū)都沒有。英文版的是真的很良心了,很多問題都有官方解答,詳細易懂。而且討論區(qū)(Discuss)也沉淀了大量優(yōu)質(zhì)內(nèi)容,甚至好過官方解答。真正能打開你思路的,很可能是討論區(qū)各路大神的思路薈萃。 PS:如果有的英文題目實在看不懂,有個小技巧,你在題目頁面的 url 里加一個 -cn,即 https:///xxx 改成 https:///xxx,這樣就能切換到相應(yīng)的中文版頁面查看。 對于初學者,強烈建議從 Explore 菜單里最下面的 Learn 開始刷,這個專題就是專門教你學習數(shù)據(jù)結(jié)構(gòu)和基本算法的,教學篇和相應(yīng)的練習題結(jié)合,不要太良心。下圖是 Learn 里面的部分內(nèi)容。 最近 Learn 專題里新增了一些內(nèi)容,我們挑數(shù)據(jù)結(jié)構(gòu)相關(guān)的內(nèi)容刷就行了,像 Ruby,Machine Learning 就沒必要刷了。刷完 Learn 專題的基礎(chǔ)內(nèi)容,基本就有能力去 Explore 菜單的 Interview 專題刷面試題,或者去 Problems 菜單,在真正的題海里遨游了。 無論刷 Explore 還是 Problems 菜單,最好一個分類一個分類的刷,不要蜻蜓點水。比如說這幾天就刷鏈表,刷完鏈表再去連刷幾天二叉樹。 這樣做是為了幫助你提取「框架」。一旦總結(jié)出針對一類問題的框架,解決同類問題可謂是手到擒來。 五、道理我都懂,還是不能堅持下去 這其實無關(guān)算法了,還是老生常談的執(zhí)行力的問題。不說什么破雞湯了,我覺得解決辦法就是「激起欲望」,注意我說的是欲望,而不是常說的興趣。拿我自己說說吧。 半年前我開始刷題,目的和大部分人都一樣的,就是為畢業(yè)找工作做準備。只不過,大部分人是等到臨近畢業(yè)了才開始刷,而我離畢業(yè)還有一陣子。這倒不是炫耀我多有覺悟,而是我承認自己的極度平凡。 首先,我真的想找到一份不錯的工作(誰都想吧?),我想要高薪呀!否則我在朋友面前,女神面前放下的騷話,最終都會反過來啪啪地打我的臉。我也是要恰飯,要面子,要虛榮心的嘛。賺錢,虛榮心,足以激起我的欲望了。 但是,我不擅長 deadline 突擊,我理解東西真的慢,所以干脆笨鳥先飛了。智商不夠,時間來湊,我沒能力兩個月突擊,干脆拉長戰(zhàn)線,打他個兩年游擊戰(zhàn),我還不信耗不死算法這個強敵。事實證明,你如果認真學習一個月,肯定能取得肉眼可見的進步了。 現(xiàn)在,我依然在堅持刷題,而且有了另一個原因:屏幕前的你。我沒想到自己的文字竟然能夠幫助到他人,甚至能得到認可。這也是虛榮心啊,我要堅持啊,不能讓我的讀者失望啊,我想讓更多的人夸我啊! 以上,不光是堅持刷算法題吧,很多場景都適用。執(zhí)行力是要靠「欲望」支撐的,我也是一凡人,只有那些看得見摸得著的東西才能使我快樂呀。 讀者不妨也嘗試把刷題學習和自己的切身利益聯(lián)系起來,這恐怕是堅持下去最簡單直白的理由了。 |
|