亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

算法越學(xué)越扎心,有沒啥破解之法?

對于算法的學(xué)習(xí),我也是從一個小白一步步走來,當(dāng)然,現(xiàn)在仍然很菜,,,不過,鑒于我覺得還有一些人比我更菜了,我決定談?wù)勎宜惴▽W(xué)習(xí)過程走過的坑,以及自己總結(jié)的一些經(jīng)驗。

切勿盲目刷題:刷題前的知識積累

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

但是,我必須提醒的是,如果你是小白,也就是說,你連常見的數(shù)據(jù)結(jié)構(gòu),如鏈表、樹以及常見的算法思想,如遞歸、枚舉、動態(tài)規(guī)劃這些都沒學(xué)過,那么,我不建議你盲目瘋狂著去刷題的。而是先去找本書先去學(xué)習(xí)這些必要的知識,然后再去刷題。

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

也就是說,假如你要去諸如leetcode這些網(wǎng)站刷題,那么,你要先具備一定的基礎(chǔ),這些基礎(chǔ)包括:

1、常見數(shù)據(jù)結(jié)構(gòu):鏈表、樹(如二叉樹)。(是的,鏈表和二叉樹是重點,圖這些可以先放著)

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

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

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

在這里,我推薦基本我大一時看過的書籍吧,感覺還是非常不錯的,如果對于數(shù)據(jù)結(jié)構(gòu)時零基礎(chǔ)的話,那么我建議你可以看《數(shù)據(jù)結(jié)構(gòu)與算法分析:C語言描述版》這本書,這本書自認(rèn)為真的很 nice,當(dāng)時我把這本書里面的全部都看了,并且 coding 了一遍,感覺整個人有了質(zhì)的飛躍。

后面我時在一些學(xué)校的OJ刷題,當(dāng)時看的一本書叫做《挑戰(zhàn)程序設(shè)計大賽》,日本作家寫的,我覺得這本書也很nice,里面有分初級,中級和高級三個模塊,基礎(chǔ)比較差的可以從初級開始看起。

總結(jié)下:

提高數(shù)據(jù)結(jié)構(gòu)與算法沒啥捷徑,最好的捷徑就是多刷題。但是,刷題的前提是你要先學(xué)會一些基本的數(shù)據(jù)結(jié)構(gòu)與算法思想。

AC不是目的,我們要追求完美

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

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

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

我做題的時候,我一看到一道題,可能第一想法就是用很粗糙的方式做,因為很多題采用暴力法都會很容易做,就是時間復(fù)雜度很高。之后,我就會慢慢思考,看看有沒其他方法來降低時間復(fù)雜度或空間復(fù)雜度。最后,我會去看一下別人的做法,當(dāng)然,并不是每道題都會這樣執(zhí)行。

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

我舉道例題吧:

問題: 一只青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法?

方法1:暴力遞歸

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

public int solve(int n){

if(n <= 2){

return n;

}else{

return solve(n-1) + solve(n-2);

}

}

這種做法的時間復(fù)雜度很高,指數(shù)級別了。但是如果你提交之后僥幸通過了,然后你就接著下一道題了,那么你就要好好想想了。

方法二:空間換時間

力求完美,我們可以考慮用空間換時間:這道題如何你去仔細(xì)想一想,會發(fā)現(xiàn)有很多是重復(fù)執(zhí)行了。不行你可以畫個圖

算法越學(xué)越扎心,有沒有什么破解之法?
 
 
 

所以可以采取下面的方法:

//用一個HashMap來保存已經(jīng)計算過的狀態(tài)

static Map<Integer,Integer> map = new HashMap();

public static int solve(int n){

if(n <= 2){

return n;

}else{//是否計算過

if(map.containsKey(n)){

return map.get(n);

}else{

int m = solve(n-1) + solve(n-2);

map.put(n, m);

return m;

}

}

}

這樣,可以大大縮短時間。也就是說,當(dāng)一道題你做了之后,發(fā)現(xiàn)時間復(fù)雜度很高,那么可以考慮下,是否有更好的方法,是否可以用空間換時間。

方法三:斐波那契數(shù)列

實際上,我們可以把空間復(fù)雜度弄的更小,不需要HashMap來保存狀態(tài):

public static int solve(int n){

if(n <= 2){

return n;

}

int f1 = 0;

int f2 = 1;

int sum = 0;

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

sum = f1 + f2;

f1 = f2;

f2 = sum;

}

return sum;

}

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

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

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

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

挑戰(zhàn)自己,跳出舒適區(qū)

什么叫舒適區(qū)?在刷題的時候,可能有一類題是你比較懂的,你每次一看就有思路,然后半個小時就擼好代碼,提交代碼,然后通過了,然后,哇,又多刷了一道題,心里很舒服。

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

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

所以,建議你,一定要學(xué)好跳出自己的舒適區(qū)。

一定要學(xué)會分類總結(jié)

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

我看過一本書,叫做《程序員代碼面試指南:IT 名企算法與數(shù)據(jù)結(jié)構(gòu)題目最優(yōu)解》,這本書就非常不錯,里面按照棧,隊列,鏈表,二叉樹,字符串等一個專題一個專題來刷的,并且每道題都給出了最優(yōu)解,而且里面的題有一定的難度,感興趣的,真心不錯,如果你把這本書的題全部搞定,并且總結(jié)相關(guān)套路,那么你的算法一定有很大的提升。

推薦一些刷題網(wǎng)站

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

在牛客網(wǎng)那里,我主要刷劍指Offer,不過那里也有個在線刷leetcode,不過里面的題量比較少。牛客網(wǎng)刷題有個非常方便的地方就是有個討論區(qū),那里會有很多大佬分享他們的解題方法,不用我們?nèi)グ俣日翌}解。所以你做完后,實在想不出,可以很方便著去看別人是怎么做的。

至于leetcode,也是大部分題目官方都有給出答案,也是個不錯的刷題網(wǎng)站。你們可以兩個挑選一個,或者兩個都刷。

當(dāng)然,還有其他刷題的網(wǎng)站,不過,其他網(wǎng)站沒刷過,不大清除如何。

學(xué)習(xí)一些解題技巧

說實話,有些題在你沒看別人的解法前,你好不知道有這么美妙優(yōu)雅的解法,看了之后,臥槽,居然還可以這樣。而我們在刷題的過程中,就要不斷累積這些技巧,當(dāng)你累計多了,你就會形成一種神經(jīng)反應(yīng),一下子就想到了某種方法。解題技巧很多,例如數(shù)組下標(biāo)法、位圖法、雙指針等等。

例如在刷題的時候,我們要學(xué)會巧用雙指針、數(shù)組下標(biāo)法、位運算等等技巧來解決問題,可能會有意想不到的效果。

再說數(shù)據(jù)結(jié)構(gòu)發(fā)重要性

前面我主要是說了我平時都是怎么學(xué)習(xí)算法的。在數(shù)據(jù)結(jié)構(gòu)方法,我只是列舉了你們一定要學(xué)習(xí)鏈表樹(二叉堆),但這是最基本的,刷題之前要掌握的,對于數(shù)據(jù)結(jié)構(gòu),我列舉下一些比較重要的:

1、鏈表(如單向鏈表、雙向鏈表)。

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

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

4、隊列、棧、矩陣。

對于這些,自己一定要動手實現(xiàn)一遍。你可以看書,也可以看視頻,新手可以先看視頻,不過前期可以看視頻,之后我建議是一定要看書。

例如對于平衡樹,可能你跟著書本的代碼實現(xiàn)之后,過陣子你就忘記,不過這不要緊,雖然你忘記了,但是如果你之前用代碼實現(xiàn)過,理解過,那么當(dāng)你再次看到的時候,會很快就記起來,很快就知道思路,而且你的抽象能力等等會在不知不覺中提升起來。之后再學(xué)習(xí)紅黑樹啊,什么數(shù)據(jù)結(jié)構(gòu)啊,都會學(xué)的很快。

最最重要

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

千萬不要找了一堆資源,訂好了學(xué)習(xí)計劃,我要留到某某天就來去做…

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

也不要覺得要學(xué)習(xí)的有好多啊,不知道從哪學(xué)習(xí)起。我上面說了,可以先學(xué)習(xí)最基本的,然后刷題,刷題是一個需要長期堅持的事情,一年,兩年。在刷題的過程中,可以穿插和學(xué)習(xí)其他數(shù)據(jù)結(jié)構(gòu)。

總結(jié)一下吧

所以我給大家的建議就是,先學(xué)習(xí)基本的數(shù)據(jù)結(jié)構(gòu)以及算法思想,不要盲目刷題,接著刷題的過程中,不能得過且過,盡量追求最優(yōu)解,還有就是要跳出舒適區(qū),逼自己成長,刷題的過程中,要學(xué)會分類總結(jié)。

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

 

 

分享到:
標(biāo)簽:算法
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定