程序員是怎么學習算法的?
在網絡上流行一句話:算法分三種,競賽的算法、面試的算法、算法。雖然這么分非常讓人無語,但其實可以去這么理解,因為競賽、面試和純理論的要求和限制是不同的,所以算法在不同的要求中展現了不同的樣子。
對于競賽來說,每道題對輸入參數和樣本量的要求都是非常明確的,同時規定的非常明確的還有空間的限制和運行時間的限制。每一個競賽選手都非常熟練怎么根據這些提前給好的限制,反推出自己需要實現一個什么樣復雜度的解法才能通過。每一行代碼包含著前輩和自己思考過的優化。
而對于面試來說,限制往往并不明確,造成這個現象的原因也很好理解。競賽中當然是分數最重要。在面試的過程中,與面試官的交流和體現自己想事情的方式、體現自己邏輯的嚴密更重要。所以同一道題,在競賽中必須寫清楚限制,而在面試中一道題剛開始的限制沒那么多,目的就是縮短你理解題目的時間,讓面試者先寫出一點什么,然后和面試官展開討論,隨著討論的深入,再逐漸的把限制聊清楚。總之在面試的場合就是想看看你想問題的習慣、軌跡以及表達能力是否符合要求。
當然,不管是什么要求下的算法,經常練習算法和數據結構題目對一個人在邏輯上的提升都是顯而易見的,在學校參加ACM并取得很好成績的同學,如果不是表達能力特別差的話,是一定會收獲很多offer的,因為思維被鍛煉的很好。
對于算法,給大家的建議:
先找到線團,然后進入線團里學著怎么玩。為了進入線團,需要先把基礎知識掌握好。《算法和數據結構》(教材),你一定要看完+理解。這里面講的都是不能再基礎的東西了,覺得講得不好,自己搜維基百科。沒辦法,如果堅持不下來,后面就受罪去吧。
對于線上刷題平臺的題目,先不找解答,先自己實現,實現的多low,復雜度多差,都堅持寫完。
然后分析出復雜度。接下來去網上找答案,看到復雜度和你一樣或比你低的,直接略過。看到比你好的,重點看,一定要理解,然后分析為什么比你的好,如果你真的理解了,你一定能找到別人優化的點。
這個過程可能是最奇妙的過程,不要給自己太大壓力,這個過程其實可以很歡樂,有想法并創造出來,練習了自己的coding能力。
別人有更好的實現,推翻了你的所有模型和幻想,你幻滅了,卻也因此找到了讓你血脈噴張方法。這個階段看似苦,實際上其樂無窮。
在學習別人解法的過程中,又了解了很多算法和數據結構。而且付出的每一滴汗水,都是結果導向的,可量化的,實實在在的。
寫寫簡單的測試函數就可以發現自己方法的運行時間和更好的解法就是沒法比。這是一個非常培養自驅力的階段,這是一個只追求解法更快更強的階段。
看到很多經典的結構,學到很多很不錯的優化。比讀那些讓你吃力的書更加快樂,也能夠一直啟發你走下去。你苦苦尋找啊,覺得好的不能再好的方法啊,直到有一天,突然看到一個更優的解法,相信你一定會一整天都在賢者時間里。
不建議剛開始刷題的人就直接在網絡上搜集文章開始學習,因為太散了,而且需要花很多時間去鑒別正確與否。
當這些內容都掌握之后,再開始在網上搜集各種各樣的題,并與網友參加各種各樣的討論,會比較高效。
把底子打好之后,對于專項算法的學習就得心應手了,而且會學的很快。 對于很龐大的算法,找例子來引導自己的思路,一點一點的接近算法的核心。唯一需要注意的是,一定要寫代碼,光看沒有用的。
對于經典算法的學習,大體上分成幾個階段:
第一階段:對于某一個具體的算法,首先要搞清楚這個算法解決的問題是什么,可能是實現一個具體的功能,也可能是在某些方面,比如時間復雜度或者空間復雜度方面很卓越,總之搞清楚這個算法被研究出來的目的是什么。第二階段:然后就要弄清楚這個算法的生存環境了,也就是看看你此時研究的東西是不是對別的知識有依賴,應該先把底層依賴的知識理解并掌握。這些問題都解決之后,就進入到算法本身的學習,理解一個算法是一件辛苦的事情,剛開始看必然會產生很多的困惑,比如經常會懷疑作者講述的內容的重要性?這些內容和這個算法有什么聯系呢?經常會有這種摸不著頭腦的感覺,其實作者做的鋪墊都是為了建立起描述算法主要內容的基礎,只有接受和理解這些基礎,才能逐漸觸碰到算法的精髓,所以耐心是很重要的。第三階段:算法的主要過程看完之后,往往還是會感到困惑,主要是不知道這個過程好在哪,這就進入了下一個階段,理解作者對這個過程在功能性或者效率卓越這件事上的解釋和證明。這才真正觸碰到算法最精髓的部分,也就是深度的理解算法的主要過程所帶來的好處,這才是最鍛煉人理解能力的地方。第四階段:上面幾點是算法學習階段的過程了,接下來就是研究算法的代碼實現,自己設計測試用例親自跑一下代碼,以及從代碼運行時間的角度分析這個算法的優勢,這也是加深對算法的理解的過程。第五階段:最后是配合相應的題目練習,讓自己通過題目練習的方式,會用、善用學習到的算法,并對這個算法產生一定的敏感程度,具體是指看到某些題目時,能夠根據題目的特點,產生與該算法的對應,也就是具備舉一反三的能力。學習永無止境,不管是算法小白,還是有一定的算法基礎,提升算法永遠都是剛需。