演算法越學越扎心,有沒啥破解之法?

2021-10-03 17:11:43 字數 4660 閱讀 7778

對於演算法的學習,我也是從乙個小白一步步走來,當然,現在仍然很菜,,,不過,鑑於我覺得還有一些人比我更菜了,我決定談談我演算法學習過程走過的坑,以及自己總結的一些經驗。

說實話,想要提高自己的演算法,真的沒啥捷徑,我覺得最好的捷徑就是腳踏實地著多動手去刷題,多刷題。

但是,我必須提醒的是,如果你是小白,也就是說,你連常見的資料結構,如鍊表、樹以及常見的演算法思想,如遞迴、列舉、動態規劃這些都沒學過,那麼,我不建議你盲目瘋狂著去刷題的。而是先去找本書先去學習這些必要的知識,然後再去刷題。

因為,如果這些基礎都不懂的話,估計一道題做了幾個小時,然後看答案都看不懂,做題沒有任何思路,這是很難受的。久而久之,估計沒啥動力了,我剛開始就是這樣,一道題答案看一天,然而還是不大懂,什麼回溯啊,暴力啊,還不知道是啥意思。

1、常見資料結構:鍊錶、樹(如二叉樹)。(是的,鍊錶和二叉樹是重點,圖這些可以先放著)

2、常見演算法思想:貪婪法、分治法、窮舉法、動態規劃,回溯法。(貪婪、窮舉、分治是基礎,動態規劃有難度,可以先放著)

以上列出來的算是最基本的吧。就是說你刷題之前,要把這些過一遍再去刷題。如果你連這些最基本的都不知道的話,那麼你再刷題的過程中,會很難受的,思路也會相對比較少。

總之,千萬不要急,先把這些基本的過一遍,力求理解,再去刷題。

在這裡,我推薦基本我大一時看過的書籍吧,感覺還是非常不錯的,如果對於資料結構時零基礎的話,那麼我建議你可以看《資料結構與演算法分析:c語言描述版》這本書,這本書自認為真的很 nice,當時我把這本書裡面的全部都看了,並且 coding 了一遍,感覺整個人有了質的飛躍。

後面我時在一些學校的oj刷題,當時看的一本書叫做《挑戰程式設計大賽》,日本作家寫的,我覺得這本書也很nice,裡面有分初級,中級和高階三個模組,基礎比較差的可以從初級開始看起。

當然,這兩本書,你可以在這個github上找到:

總結下:提高資料結構與演算法沒啥捷徑,最好的捷徑就是多刷題。但是,刷題的前提是你要先學會一些基本的資料結構與演算法思想。

如何刷題?如何對待一道演算法題?

我覺得,在做題的時候,一定要追求完美,千萬不要把一道題做出來之後,提交通過,然後就趕緊下一道。我認為這意義不大,因為一道題的解法太多了,有些解法態粗糙了,我們應該要尋找最優的方法。

演算法能力的提公升和做題的數量是有一定的關係,但並不是線性關係。也就是說,在做題的時候,要力求一題多解,如果自己實在想不出來其他辦法了,可以去看看別人是怎麼做的,千萬不要覺得模仿別人的做法是件丟人的事。

我做題的時候,我一看到一道題,可能第一想法就是用很粗糙的方式做,因為很多題採用暴力法都會很容易做,就是時間複雜度很高。之後,我就會慢慢思考,看看有沒其他方法來降低時間複雜度或空間複雜度。最後,我會去看一下別人的做法,當然,並不是每道題都會這樣執行。

衡量一道演算法題的好壞無非就是時間複雜度空間複雜度,所以我們要力求完美,就要把這兩個降到最低,令他們相輔相成。

我舉道例題吧:

這道題我在以前的分章分析過,不懂的可以先看下之前寫的:遞迴與動態規劃—基礎篇1

方法1::暴力遞迴

這道題不難,或許你會採取下面的做法:

public int solve(int n)else

}

這種做法的時間複雜度很高,指數級別了。但是如果你提交之後僥倖通過了,然後你就接著下一道題了,那麼你就要好好想想了。

方法二:空間換時間

//用乙個hashmap來儲存已經計算過的狀態

static mapmap = new hashmap();

public static int solve(int n)elseelse}}

這樣,可以大大縮短時間。也就是說,當一道題你做了之後,發現時間複雜度很高,那麼可以考慮下,是否有更好的方法,是否可以用空間換時間。

方法三:斐波那契數列

實際上,我們可以把空間複雜度弄的更小,不需要hashmap來儲存狀態:

public static int solve(int n) 

int f1 = 0;

int f2 = 1;

int sum = 0;

for(int i = 1; i<= n; i++)

return sum;

}

我弄這道題給你們看,並不是在教你們這道題怎麼做,而是有以下目的:

1、在刷題的時候,我們要力求完美。

2、我想不到這些方法啊,怎麼辦?那麼你就可以去看別人的做法,之後,遇到類似的題,你就會更有思路,更知道往哪個方向想。

3、可以從簡單暴力入手做一道題,在考慮空間與時間之間的衡量,一點點去優化。

什麼叫舒適區?在刷題的時候,可能有一類題是你比較懂的,你每次一看就有思路,然後半個小時就擼好**,提交**,然後通過了,然後,哇,又多刷了一道題,心裡很舒服。

但是,記住,前期你可以多刷這種題練手,提公升自己的樂趣,但,我還是建議你慢慢跳出舒適區,去做一些自己不擅長的題,並且找段時間一直刷這種題。例如,我覺得我在遞迴方面的題還是挺強的,

但是,我對動態規劃的題,很菜,每次都要想好久,每次遇到這種題都有點害怕,沒什麼信心。不過有段時間我覺得只刷動態規劃的題,直接在 leetcode 選定專題,連續做了四五十道,剛開始很難受,後來就慢慢知道了套路了,一道題從兩三個小時最後縮到半小時,簡單的十幾分鐘就搞定。感覺自己對這型別的題也不懼怕的。

當然,對於動態規劃的學習,大家也可以看我這篇廣受好評的文章:為什麼你學不過動態規劃?告別動態規劃,談談我的經驗

所以,建議你,一定要學好跳出自己的舒適區。

有些人以為 leetcode 的題刷的越多,就一定能越厲害,其實不然,leetcode 雖然有 1000 多道題,但題型就那麼幾類,我們前期在刷的時候,我是建議按照題型分類刷題的,例如我這整理刷二叉樹相關,然後刷鍊錶相關,然後二分法,然後遞迴等等,每刷一種題型,都要研究他們的套路,如果你願意去總結,那麼 leetcode 的題,其實你刷幾百道,有目的、挑選的刷,我覺得就差不多了。

我看過一本書,叫做《程式設計師**面試指南:it 名企演算法與資料結構題目最優解》,這本書就非常不錯,裡面按照棧,佇列,鍊錶,二叉樹,字串等乙個專題乙個專題來刷的,並且每道題都給出了最優解,而且裡面的題有一定的難度,感興趣的,真心不錯,如果你把這本書的題全部搞定,並且總結相關套路,那麼你的演算法一定有很大的提公升。

我一般是在leetcode和牛客網刷題,感覺挺不錯,題目難度不是很大。

至於leetcode,也是大部分題目官方都有給出答案,也是個不錯的刷題**。你們可以兩個挑選乙個,或者兩個都刷。

當然,還有其他刷題的**,不過,其他**沒刷過,不大清除如何。

至於leetcode,有中文版和英文版

leetcode有中文版

英文版根據自己的興趣選。

說實話,有些題在你沒看別人的解法前,你好不知道有這麼美妙優雅的解法,看了之後,臥槽,居然還可以這樣。而我們在刷題的過程中,就要不斷累積這些技巧,當你累計多了,你就會形成一種

神經反應,一下子就想到了某種方法。解題技巧很多,例如陣列下標法、位圖法、雙指標等等,我自己也分享過一篇總結一些演算法技巧的文章

推薦閱讀:一些常用的演算法技巧總結

分享一道解法巧妙的演算法題

【演算法技巧】位運算裝逼指南

前面我主要是說了我平時都是怎麼學習演算法的。在資料結構方法,我只是列舉了你們一定要學習鍊錶樹(二叉堆),但這是最基本的,刷題之前要掌握的,對於資料結構,我列舉下一些比較重要的:

1、鍊錶(如單向鍊錶、雙向鍊錶)。

2、樹(如二叉樹、平衡樹、紅黑樹)。

3、圖(如最短路徑的幾種演算法)。

4、佇列、棧、矩陣。

例如對於平衡樹,可能你跟著書本的**實現之後,過陣子你就忘記,不過這不要緊,雖然你忘記了,但是如果你之前用**實現過,理解過,那麼當你再次看到的時候,會很快就記起來,很快就知道思路,而且你的抽象能力等等會在不知不覺中提公升起來。之後再學習紅黑樹啊,什麼資料結構啊,都會學的很快。

對於有哪些值得學習的演算法,我之前也總結過,這裡推薦給大家程式設計師必須掌握的核心演算法有哪些?,這篇文章居然 40多萬閱讀量了,有點受寵若驚。

動手去做,動手去做,動手去做。重要的話說三遍。

千萬不要找了一堆資源,訂好了學習計畫,我要留到某某天就來去做…

千萬不要這樣,而是當你激情來的時候,就馬上去幹,千萬不要留到某個放假日啊什麼鬼了,很多這種想法的人,最後會啥也沒做的。

也不要覺得要學習的有好多啊,不知道從哪學習起。我上面說了,可以先學習最基本的,然後刷題,刷題是乙個需要長期堅持的事情,一年,兩年。在刷題的過程中,可以穿插和學習其他資料結構。

所以我給大家的建議就是,先學習基本的資料結構以及演算法思想,不要盲目刷題,接著刷題的過程中,不能得過且過,盡量追求最優解,還有就是要跳出舒適區,逼自己成長,刷題的過程中,要學會分類總結。

當然,最重要的,就是你去動手了,不然,一切免談!

看在熬夜寫過的份上,送我個贊唄,嘻嘻。

越往下讀心越疼 徐志摩

1.如果曾經有乙個人為了你而等待,不管是三年還是三個月,請不要那樣輕率地選擇拒絕。這世間的緣分並不像空氣那樣廉價,再平凡不過的相遇與相識,亦是前世的修行在今生的回報。在親情以外,沒有誰人能夠輕易而又不求回報地為乙個人付出一段寂寞的等待。即使沒有欣喜的結果,也一度溫暖過冷若冰霜的心靈。2.有時候,同樣...

隨工作年限增長,我越走越窄,越心塞!

網路編輯部整理 1 無奈,所在行業走下坡 統行業走下坡路就回家鄉發展,找了一家食品公司做業務,工作快 4年了,感覺發展空間不大,現在想找家有發展空間待遇好點的公司。無憂專家 薪資的決定因素包括 行業景氣度 城市薪資水平 公司本身的實力及薪資給付水平 個人能力情況等。回到你的問題,實際上近兩年傳統行業...

前端越學越迷茫,如何跳出學習前端的5大誤區

首先,學習前端開發是乙個漫長的過程,我覺得學習最重要就是堅持和多練。不要假裝很努力,結果是不會陪你演戲的。還有乙個是正確的學習方法和學習方向,如果你一開始學習方向不對,學習肯定就走了很多彎路了,而且可能一條彎路走到底,必然跟一些人的技術能力還是有一定的差距的。我覺得學習前端,一直要抱有堅持學習的好習...