算法很難?那是你沒(méi)找到方法
“算法是特定問(wèn)題求解步驟的描述算法是獨(dú)立存在的一種解決問(wèn)題的方法和思想,算法很重要,但算法也是學(xué)起來(lái)最難,最令人生畏的。”
小伙伴們?cè)谒㈩}的時(shí)候不知道有沒(méi)有遇到以下情況,拿到題目后就開(kāi)始想著怎么寫(xiě)代碼,結(jié)果寫(xiě)了大半天,發(fā)現(xiàn)越寫(xiě)越亂,最后就寫(xiě)不下去了,又或者是看到題目后,一臉懵逼,完全不知道怎么下手。學(xué)算法,刷題蠻干是不行的,需要遵循科學(xué)的技巧。
(一)、算法不是拼智商
算法不是并純粹拼智商,“智商高”就一定很厲害?“不夠聰明”就一定不行!當(dāng)然不是的,算法是一種技能,是可以通過(guò)科學(xué)合理的方式訓(xùn)練出來(lái)的能力。智商的高低,當(dāng)然會(huì)有一定的影響,但這個(gè)先天因素?zé)o法改變,而科學(xué)合理的方法是大家都可以掌握的。首要的一點(diǎn),是要意識(shí)到,算法不是只拼智商的,也是可以經(jīng)由后天訓(xùn)練習(xí)得的。
(二)、難度要循序漸進(jìn)
有些同學(xué)喜歡不明所以的上來(lái)就是干,選擇終極難度的題目,覺(jué)得自己只要做出最難的,其它的就迎刃而解了。這種急于求成的思想要不得。算法訓(xùn)練是一個(gè)系統(tǒng)工程,需要循序漸進(jìn),太過(guò)于急功近利,反而容易因做不出難題而產(chǎn)生挫敗感,帶來(lái)反效果。記得我有一個(gè)同事就做了次類(lèi)似的事情。我們當(dāng)時(shí)剛聽(tīng)說(shuō)有l(wèi)eetcode,就想上去試試,他上去后就挑了一道困難里面還屬于比較難的題目,結(jié)果想了大半天也沒(méi)做出來(lái),搞到自己特別沮喪。事后你會(huì)發(fā)現(xiàn)這種做法效率很低,那道題目就算被做出來(lái)了,也不代表就可以解出其它的題目。
(三)、合理的做法是循序漸進(jìn)
如果你本身有基礎(chǔ),熟練度高,那你刷簡(jiǎn)單的leetcode應(yīng)該是幾分鐘一題,幾分鐘一題的,花不了你多少時(shí)間。如果你刷簡(jiǎn)單都花費(fèi)很長(zhǎng)時(shí)間,說(shuō)明熟練度不夠,就更應(yīng)該從簡(jiǎn)單開(kāi)始。然后過(guò)度到中等,再過(guò)度到困難。
目前國(guó)內(nèi)大廠的算法考察,基本不會(huì)超過(guò)leetcode 中等難度,上限難度基本都是leetcode 中等題里面的中等難度(有點(diǎn)拗口,leetcode 中等難度里面也有分檔次),如果你能夠在20分鐘內(nèi),做出這種難度的題目,國(guó)內(nèi)大廠的算法面試,基本可以暢通無(wú)阻。
(一)、按算法分類(lèi)來(lái)選題
選擇題目,除了在難度上要循序漸進(jìn),還建議在算法上進(jìn)行劃分?;镜乃惴〝?shù)據(jù)結(jié)構(gòu)是有限的。比如說(shuō)鏈表,二叉樹(shù),二分查找,動(dòng)態(tài)規(guī)劃,哈希表。我喜歡按算法的分類(lèi)來(lái)選題和刷題,比如一個(gè)時(shí)間段,只刷鏈表題,待刷得差不多的時(shí)候,接下來(lái)再刷二叉樹(shù)的題。這種做法可以極大的提高刷題的速度,而且能帶來(lái)更好的效果。
1、持續(xù)地刷同個(gè)類(lèi)型的題目,可以不斷地鞏固和加深理解。
2、可以更全面地接觸這個(gè)數(shù)據(jù)結(jié)構(gòu),算法的各個(gè)變種,這會(huì)促使你對(duì)這個(gè)數(shù)據(jù)結(jié)構(gòu),算法的理解更加全面和深刻,學(xué)習(xí)的效率會(huì)更高。
所以在一段時(shí)間內(nèi),持續(xù)地刷特定類(lèi)別的題目,可以帶來(lái)事半功倍的效果。當(dāng)然,在能力已經(jīng)比較強(qiáng)的時(shí)候,可以采用打散的方式來(lái)刷題,可以更好地鍛煉思維的靈活性和應(yīng)變能力,但初期或能力較弱的時(shí)候,按分類(lèi)選題,是比較好的。
(二)、解題三部曲
在具體做題的時(shí)候,可以采用以下三個(gè)步驟來(lái)進(jìn)行,拿到題目后不要立馬開(kāi)干,想著下面的三個(gè)步驟,一步一步地來(lái)。
1、 看懂題目
看懂題目。有的題目很直接,直接告訴你要解決的問(wèn)題是什么,題目本身甚至都包含了對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)和需要用到的算法;有的題目很隱晦,看了半天不知道它到底要解決什么問(wèn)題,可以用什么算法和數(shù)據(jù)結(jié)構(gòu)來(lái)解。所以,看到題目后,一定要先確保自己理解清楚了。
我的一個(gè)經(jīng)驗(yàn)是,拿到一個(gè)題目后,看5分鐘,如果5分鐘之內(nèi)看不懂,我就mark 下來(lái),留到后面再做,要不很影響刷題的心情。
不過(guò)就leetcode 來(lái)說(shuō),這樣的題目不多?;径寄茉谠?分鐘內(nèi)看懂。
2、分析,推導(dǎo)解法
分析推導(dǎo)題目的解法:這個(gè)步驟要有意識(shí)地單獨(dú)拎出來(lái),不要跟編碼步驟混淆在一起。也就是說(shuō),你在分析推導(dǎo)題目解法的時(shí)候,不要去想任何實(shí)現(xiàn)相關(guān)地事情,不用去想代碼怎么寫(xiě),不用去想要用什么庫(kù),定義什么變量,用多少層循環(huán),都不要想,就想著在邏輯上,這道題目要怎么解。
這樣做可以極大地降低你的心智負(fù)擔(dān),使你高效地想出題目的解法。對(duì)于如何將想法變成代碼,可以留在下一個(gè)步驟,單獨(dú)來(lái)進(jìn)行。
3、將思路轉(zhuǎn)換為代碼
當(dāng)你確定題目都已經(jīng)理解,并且分析推導(dǎo)出了題目的解法后,你才開(kāi)始來(lái)思考如何將自己的思路轉(zhuǎn)換成代碼。是地,將思路轉(zhuǎn)換成代碼,可以是一個(gè)單獨(dú)地步驟,在實(shí)際工作中,其實(shí)也是很重要的一個(gè)能力。
有時(shí),將一個(gè)思路轉(zhuǎn)換成算法是很容易且自然的;但有時(shí),有些思路轉(zhuǎn)換成代碼,是很有難度的事情?;蛘吣阌畜w會(huì),分析推導(dǎo)只用了不到十分鐘,結(jié)果代碼寫(xiě)了半小時(shí)還寫(xiě)不完整。
怎么定義變量,保存狀態(tài),用遞歸,還是用循環(huán)加輔助數(shù)據(jù)結(jié)構(gòu)等等,都是將思路轉(zhuǎn)換成代碼要做的事情,這個(gè)能力也需要刻意地去練習(xí)。
(三)、算法的封裝
說(shuō)點(diǎn)更細(xì)節(jié)的東西,算法的封裝,軟件設(shè)計(jì)里面,最關(guān)鍵的思想就是抽象和封裝了。
其實(shí)解題也可以用到這種思路。
比如一道題目的正確解法是先排序,再進(jìn)行二分查找,那你的腦子里面只要記得,快速排序和二分查找,就可以了,不需要去想,快速排序和二分查找的具體實(shí)現(xiàn)。就像我們?cè)趯?xiě)代碼的時(shí)候,遇到排序,查找,我們一般都直接使用了現(xiàn)成的函數(shù)庫(kù),而不需要自己動(dòng)手再寫(xiě)一遍。這個(gè)是代碼層面封裝帶來(lái)的好處,思維層面的封裝也是一樣的道理。
這種封裝思想在做題的時(shí)候可以極大地減輕我們的心智負(fù)擔(dān),使得自己的腦力可以發(fā)揮在問(wèn)題的核心點(diǎn)上。用封裝的思維去解題,你的解題能力會(huì)有快速地提升,封裝的思想可以用于 “ 2.分析,推導(dǎo)解法” 的過(guò)程,在 “ 3.將思路轉(zhuǎn)換為代碼” 的過(guò)程,更是可以用語(yǔ)言?xún)?nèi)置的算法函數(shù),數(shù)據(jù)結(jié)構(gòu)來(lái)直接實(shí)現(xiàn),也使得從思路轉(zhuǎn)換到代碼的過(guò)程更加的直觀和自然。
在實(shí)際的面試或比賽中,除非有特殊說(shuō)明,一般都可以放心地使用語(yǔ)言的內(nèi)置算法和數(shù)據(jù)結(jié)構(gòu),然后你可能會(huì)問(wèn),對(duì)于像排序,查找這些基礎(chǔ)的算法應(yīng)該怎么對(duì)待呢?我的建議是可以把它們當(dāng)作重要算法來(lái)刻意練習(xí)。
快排,快搜,堆排序等,我們可以稱(chēng)它們?yōu)樵惴?。?duì)于這些算法的刻意練習(xí)。一開(kāi)始的時(shí)候,要看算法書(shū)的描述,確保自己理解了算法的思路,然后嘗試自己實(shí)現(xiàn)一遍。實(shí)在寫(xiě)不出來(lái),就參照或者直接抄。一個(gè)算法花幾天的時(shí)間,大部分人都是可以理解并自己實(shí)現(xiàn)出來(lái)的。(排除一些特別難的,需要更長(zhǎng)的時(shí)間)。
(四)、保持持續(xù)的動(dòng)力
算法能力的提升,是一個(gè)長(zhǎng)期的事情,需要持續(xù)地學(xué)習(xí)和做題,而刷題又是個(gè)比較枯燥的過(guò)程,在遇到難題的時(shí)候,很容易產(chǎn)生挫敗感,甚至導(dǎo)致直接放棄。
所以這里需要特別關(guān)注刷題時(shí)的正反饋。如果你老是無(wú)法解出某個(gè)難度或某個(gè)類(lèi)別的題目的時(shí)候,你就要考慮降低難度,或者安排額外的時(shí)間,去更全面的復(fù)習(xí)特定的算法和數(shù)據(jù)結(jié)構(gòu)了。
注意不要死磕!算法學(xué)習(xí),特別講求方法和技巧,死磕非但磕不過(guò)去,還可能留下對(duì)算法的心里陰影,導(dǎo)致學(xué)習(xí)障礙。
聯(lián)系客服