0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

大牛分享平時(shí)如何學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:未知 ? 作者:胡薇 ? 2018-11-02 11:25 ? 次閱讀

一個(gè)熱愛編程的在校生,我的世界不只有coding,還有writing。目前維護(hù)訂閱號(hào)「苦逼的碼農(nóng)」,專注于寫「算法與數(shù)據(jù)結(jié)構(gòu)」,「Java」,「計(jì)算機(jī)網(wǎng)絡(luò)」。

數(shù)據(jù)結(jié)構(gòu)與算法的地位對(duì)于一個(gè)程序員來說不言而喻。今天這篇文章不是來勸你們學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法的,也不是來和你們說數(shù)據(jù)結(jié)構(gòu)與算法有多重要。

主要是最近幾天后臺(tái)有讀者問我是如何學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法的,有沒有什么捷徑,是要看視頻還是看書,去哪刷題等…..而且有些還是大三大四的,搞的我都替你們著急、擔(dān)心…..

所以我今天就分享下自己平時(shí)都是怎么學(xué)習(xí)的。

學(xué)習(xí)算法的捷徑就是多刷題

說實(shí)話,要說捷徑,我覺得就是腳踏實(shí)地著多動(dòng)手去刷題,多刷題。

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

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

1、常見數(shù)據(jù)結(jié)構(gòu):鏈表、樹(如二叉樹)。

2、常見算法思想:貪婪法、分治法、窮舉法、動(dòng)態(tài)規(guī)劃,回溯法。

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

總之,千萬不要急,先把這些基本的過一遍,力求理解,再去刷題。這些基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)與算法,我是在大一第二學(xué)期學(xué)的,我沒看視頻,我是通過看書學(xué)的,那時(shí)候看的書是:

1、算法分析與分析基礎(chǔ):這本比較簡單,推薦新手看。

2、數(shù)據(jù)結(jié)構(gòu)與算法分析—-C語言描述:代碼用C寫的,推薦看。

3、挑戰(zhàn)程序設(shè)計(jì)競賽(第二版):也是很不錯(cuò)的一本書,推薦看。

具體可以看我的另外一篇文章,里面是介紹這幾本書的:算法與數(shù)據(jù)結(jié)構(gòu)書籍與視頻福利

說實(shí)話,我那一學(xué)期的時(shí)間幾乎都花在數(shù)據(jù)結(jié)構(gòu)與算法上,但刷的題很少,只是書本上的一些例題。所以當(dāng)我把這些基本的過一遍之后,再去一些網(wǎng)站刷題依舊非常菜。

所以你們千萬別指望以為自己把這些思想學(xué)完之后刷題會(huì)很牛,只有多刷題,只有多動(dòng)手實(shí)踐,你的靈敏度才會(huì)提高起來。

在這里說一下前陣子有個(gè)非?;鸨膶凇?【數(shù)據(jù)結(jié)構(gòu)與算法之美】

我沒買這個(gè)專欄,我想說的是,買了就一定要去看,千萬別浪費(fèi)。也千萬不要覺得學(xué)完這個(gè)專欄你就會(huì)變的多牛逼,如果你只是跟著進(jìn)度去學(xué)習(xí)這個(gè)專欄,自己沒有花時(shí)間去刷題、去動(dòng)手時(shí)間。那我可以保證,你學(xué)完之后還是那么菜。

總結(jié)下:

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

追求完美

如何刷題?如何對(duì)待一道算法題?

我覺得,在做題的時(shí)候,一定要追求完美,千萬不要把一道題做出來之后,提交通過,然后就趕緊下一道。

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

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

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

我舉道例題吧:

問題:一只青蛙一次可以跳上1級(jí)臺(tái)階,也可以跳上2級(jí)。求該青蛙跳上一個(gè)n級(jí)的臺(tái)階總共有多少種跳法?

這道題我在以前的分章分析過,不懂的可以先看下之前寫的:遞歸與動(dòng)態(tài)規(guī)劃---基礎(chǔ)篇1

方法1::暴力遞歸

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

public static int solve(int n){ if(n == 1 || n == 2){ return n; }else if(n <= 0){ ? ? ? ?return 0; ? ?}else{ ? ? ? ?return solve(n-1) + solve(n-2); ? ?}}

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

方法二:空間換時(shí)間

力求完美,我們可以考慮用空間換時(shí)間:這道題如何你去仔細(xì)想一想,會(huì)發(fā)現(xiàn)有很多是重復(fù)執(zhí)行了。所以可以采取下面的方法:

//用一個(gè)HashMap來保存已經(jīng)計(jì)算過的狀態(tài)static Map map = new HashMap();public static int solve(int n){ if(n <= 0)return 0; ? ?else if(n <= 2){ ? ? ? ?return n; ? ?}else{//是否計(jì)算過 ? ? ? ?if(map.containsKey(n)){ ? ? ? ? ? ?return map.get(n); ? ? ? ?}else{ ? ? ? ? ? ?int m = solve(n-1) + solve(n-2); ? ? ? ? ? ?map.put(n, m); ? ? ? ? ? ?return m; ? ? ? ?} ? ?}}

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

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

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

public static int solve(int n){ if(n <= 0) ? ? ? return 0; ? ?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、在刷題的時(shí)候,我們要力求完美。

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

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

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

我一般是在leetcode和??途W(wǎng)刷題,感覺挺不錯(cuò),題目難度不是很大。

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

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

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

再說數(shù)據(jù)結(jié)構(gòu)

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

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

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

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

4、隊(duì)列、棧、矩陣。

對(duì)于這些,自己一定要?jiǎng)邮謱?shí)現(xiàn)一遍。你可以看書,也可以看視頻,新手可以先看視頻,不過前期可以看視頻,之后我建議是一定要看書。

視頻和書我以前有推薦過:算法與數(shù)據(jù)結(jié)構(gòu)書籍與視頻福利

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

最最重要

動(dòng)手去做,動(dòng)手去做,動(dòng)手去做。重要的話說三遍。

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

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

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

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4552

    瀏覽量

    92019
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    568

    瀏覽量

    40030

原文標(biāo)題:我是如何學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法的?

文章出處:【微信號(hào):TheAlgorithm,微信公眾號(hào):算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    嵌入式常用數(shù)據(jù)結(jié)構(gòu)有哪些

    在嵌入式編程中,數(shù)據(jù)結(jié)構(gòu)的選擇和使用對(duì)于程序的性能、內(nèi)存管理以及開發(fā)效率都具有重要影響。嵌入式系統(tǒng)由于資源受限(如處理器速度、內(nèi)存大小等),因此對(duì)數(shù)據(jù)結(jié)構(gòu)的選擇和使用尤為關(guān)鍵。以下是嵌入式編程中常用的幾種數(shù)據(jù)結(jié)構(gòu),結(jié)合具體特點(diǎn)和
    的頭像 發(fā)表于 09-02 15:25 ?218次閱讀

    探索編程世界的七大數(shù)據(jù)結(jié)構(gòu)

    結(jié)構(gòu)就像是一顆倒掛的小樹,有根、有枝、有葉。它是一種非線性的數(shù)據(jù)結(jié)構(gòu),以層級(jí)的方式存儲(chǔ)數(shù)據(jù),頂部是根節(jié)點(diǎn),底部是葉節(jié)點(diǎn)。
    的頭像 發(fā)表于 04-16 12:04 ?286次閱讀

    TASKING編譯器是否可以將數(shù)據(jù)結(jié)構(gòu)設(shè)置為 \"打包\"?

    TASKING 編譯器是否可以將數(shù)據(jù)結(jié)構(gòu)設(shè)置為 \"打包\"? GCC 很早以前就提供了這種可能性,可以將__attribute__((packed))與對(duì)齊指令結(jié)合使用。 對(duì)于
    發(fā)表于 03-05 06:00

    矢量與柵格數(shù)據(jù)結(jié)構(gòu)各有什么特征

    矢量數(shù)據(jù)結(jié)構(gòu)和柵格數(shù)據(jù)結(jié)構(gòu)是地理信息系統(tǒng)(GIS)中最常用的兩種數(shù)據(jù)結(jié)構(gòu)。它們?cè)诖鎯?chǔ)和表示地理要素上有著不同的方法和特征。在接下來的文章中,我們將詳細(xì)介紹這兩種數(shù)據(jù)結(jié)構(gòu)并比較它們的特點(diǎn)
    的頭像 發(fā)表于 02-25 15:06 ?1655次閱讀

    區(qū)塊鏈?zhǔn)鞘裁礃拥?b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)組織

    區(qū)塊鏈?zhǔn)且环N特殊的數(shù)據(jù)結(jié)構(gòu),它以分布式、去中心化的方式組織和存儲(chǔ)數(shù)據(jù)。區(qū)塊鏈的核心原理是將數(shù)據(jù)分布在網(wǎng)絡(luò)的各個(gè)節(jié)點(diǎn)上,通過密碼學(xué)算法保證數(shù)據(jù)
    的頭像 發(fā)表于 01-11 10:57 ?1373次閱讀

    C語言數(shù)據(jù)結(jié)構(gòu)之跳表詳解

    大家好,今天分享一篇C語言數(shù)據(jù)結(jié)構(gòu)相關(guān)的文章--跳表。
    的頭像 發(fā)表于 12-29 09:32 ?718次閱讀
    C語言<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>之跳表詳解

    redis數(shù)據(jù)結(jié)構(gòu)的底層實(shí)現(xiàn)

    Redis是一種內(nèi)存鍵值數(shù)據(jù)庫,常用于緩存、消息隊(duì)列、實(shí)時(shí)數(shù)據(jù)分析等場景。它的高性能得益于其精心設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)和底層實(shí)現(xiàn)。本文將詳細(xì)介紹Redis常用的數(shù)據(jù)結(jié)構(gòu)和它們的底層實(shí)現(xiàn)。 Re
    的頭像 發(fā)表于 12-05 10:14 ?517次閱讀

    不同數(shù)據(jù)結(jié)構(gòu)的定義代碼

    數(shù)據(jù)結(jié)構(gòu)是相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合。
    的頭像 發(fā)表于 11-29 14:13 ?535次閱讀

    redis的五種數(shù)據(jù)類型底層數(shù)據(jù)結(jié)構(gòu)

    Redis是一種內(nèi)存數(shù)據(jù)存儲(chǔ)系統(tǒng),支持多種數(shù)據(jù)結(jié)構(gòu)。這些數(shù)據(jù)結(jié)構(gòu)不僅可以滿足常見的存儲(chǔ)需求,還能夠通過其底層數(shù)據(jù)結(jié)構(gòu)提供高效的操作和查詢。以下是Redis中常用的五種
    的頭像 發(fā)表于 11-16 11:18 ?605次閱讀

    ringbuffer數(shù)據(jù)結(jié)構(gòu)介紹

    最近在研究srsLTE的代碼,其中就發(fā)現(xiàn)一個(gè)有意思的數(shù)據(jù)結(jié)構(gòu)------ringbuffer。 雖然,這是一個(gè)很基本的數(shù)據(jù)結(jié)構(gòu),但時(shí),它在LTE這種通信協(xié)議棧系統(tǒng)中卻大行其道,也是很容易被協(xié)議
    的頭像 發(fā)表于 11-13 10:44 ?1274次閱讀
    ringbuffer<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>介紹

    epoll的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)

    一、epoll的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu) 在開始研究源代碼之前,我們先看一下 epoll 中使用的數(shù)據(jù)結(jié)構(gòu),分別是 eventpoll、epitem 和 eppoll_entry。 1、eventpoll 我們
    的頭像 發(fā)表于 11-10 10:20 ?630次閱讀
    epoll的基礎(chǔ)<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>

    Linux內(nèi)核中使用的數(shù)據(jù)結(jié)構(gòu)

    Linux內(nèi)核代碼中廣泛使用了數(shù)據(jù)結(jié)構(gòu)算法,其中最常用的兩個(gè)是鏈表和紅黑樹。 鏈表 Linux內(nèi)核代碼大量使用了鏈表這種數(shù)據(jù)結(jié)構(gòu)。鏈表是在解決數(shù)組不能動(dòng)態(tài)擴(kuò)展這個(gè)缺陷而產(chǎn)生的一種數(shù)據(jù)結(jié)構(gòu)
    的頭像 發(fā)表于 11-09 14:24 ?383次閱讀
    Linux內(nèi)核中使用的<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>

    Linux GIC驅(qū)動(dòng)數(shù)據(jù)結(jié)構(gòu)分析

    數(shù)據(jù)結(jié)構(gòu)分析 先來張圖: GIC驅(qū)動(dòng)中,使用 struct gic_chip_data 結(jié)構(gòu)體來描述GIC控制器的信息,整個(gè)驅(qū)動(dòng)都是圍繞著該結(jié)構(gòu)體的初始化,驅(qū)動(dòng)中將函數(shù)指針都初始化好,實(shí)際的工作
    的頭像 發(fā)表于 09-28 15:18 ?462次閱讀
    Linux GIC驅(qū)動(dòng)<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>分析

    變長數(shù)據(jù)數(shù)據(jù)結(jié)構(gòu)定義

    用方便的呢? GNU C 的0長度數(shù)組(變長數(shù)組/柔性數(shù)組)就是這樣一個(gè)擴(kuò)展. 對(duì)于 0長數(shù)組 的這個(gè)特點(diǎn),很容易構(gòu)造出變成結(jié)構(gòu)體,如緩沖區(qū),數(shù)據(jù)包等等: 數(shù)據(jù)結(jié)構(gòu)定義 // 0長度數(shù)組 struct zero_buffer{
    的頭像 發(fā)表于 09-27 15:08 ?601次閱讀

    stm32的8位數(shù)據(jù)結(jié)構(gòu)怎么判斷正負(fù)?

    stm32的8位數(shù)據(jù)結(jié)構(gòu)怎么判斷正負(fù),char變量不能為負(fù),不想用int,我記得51單片機(jī)char可以判斷正負(fù)
    發(fā)表于 09-22 07:15