選一本出色的教材.有條件就看英文的,然後給自己一個環境,例如LINUX+GCC+GDB,用純粹的語言去在解決問題的過程中學習演算法.
沒有目的性去學習,往往效率不高,可以找一些ONLINE JUDGE的題目做做.例如Welcome To PKU JudgeOnline,對著裡面的問題,先自己思考,嘗試編程解決,如果不能解決,就翻翻演算法書,想想為什麼.
如果還是不行,那就上網看看別人有沒有解決掉,怎麼做,看看他們用到什麼演算法,比對著,然後進一步自己去實現.
有時候對於演算法的問題的實現,你在實現之前也許會卡住,但是在編程過程中,隨著你的鍛煉和熟練度的提高.會有那麼一天你覺得什麼都通了,而且,你是在用的過程中學習.堅持走下去,一定事半功倍.
「cracking the coding interview」,題目是按照array, stack&queue, 鏈表,樹圖,遞歸這種章節安排的,每章節題目7-8個,不多,難度中等,找感覺很有幫助。第一遍自己寫不出來的話(我就是,這么弱!),畫圖分析,抄背默。一遍做完再做一遍,第二遍就快很多,理解也深刻了,所謂讀書百遍,其意自現,演算法也一樣。
不要一開始就看《演算法導論》,這本書有太多關於演算法的數學證明.
推薦你看看這本:演算法(第4版) (豆瓣),作者是高德納的學生:塞奇威克 (Robert Sedgewick)
書中演算法代碼主要是用Java編寫,裡面有大量的圖來讓你明白例如:排序,查找,樹和圖的演算法運行過程。
這本書的目錄編排也很清晰,他就告訴你演算法主要就可以分為:排序,查找,圖和字元串。從這4個方面可以演化出很多演算法,最關鍵是:這本書的作者不但是在告訴你what,而且告訴你why(分析各種演算法的優缺點)
這本書其他好的地方
比如講到快速排序,很多書可能講了快速排序的原理就完了。但這本書就直接講了原始的快速排序可以改進的地方:1. 在小數組上,切換到插入排序;2. 三取樣切分;3. 三向切分的快速排序。
優先隊列怎麼和排序演算法扯上關系呢?其實優先隊列就是可以用堆排序來實現,堆排序的時間復雜度和快速排序是一樣的,但是實際中為什麼堆排序的運行時間要比快速排序多呢?因為這和CPU的Cache命中率有關系,堆排序不符合演算法運行的局部性原則
比如書中2.5節,講了排序演算法的實際用途,這本書不光告訴你演算法的原理,還告訴你演算法的用途。
⑵ 如何正確的刷題刷題的重要性如何
在日常地學習當中,我們總是離不開讀書和刷題這兩種方式。讀書讓我們更加了解課程的基本內容,刷題則讓我們能夠更好地掌握知識。尤其是處在備考期的學生們,掌握科學的刷題方法,能夠使我們順利地通過考試,取得優異的成績。
掌握了刷題的技巧,還應該了解刷題的的重要性。只有真正理解刷題對於我們的意義,才能夠靜下心來好好刷題、認真刷題。我們要明白刷題是取得進步的過程,是了解自我的手段,是培養自己思維能力的方法。當我們真正掌握知識點時,刷題的目的也就達到了。
⑶ 在h和poj上刷題和自己學習演算法知識應該怎樣結合
比如,你想學習搜索演算法的話,那麼你就先看看書,學習一下,之後到各oj上去刷題,刷搜索方面的題,在網上有很多給oj題目歸類的文章,你就去找找,我覺得這樣會很快的提高的!
⑷ 如何學好演算法
演算法是一個積累的過程,最現實的方法就是從題目中學演算法。http://acm.h.e.cn/ 這是一個比較牛逼的網站,我想學編程的人都知道,在裡面刷題目,然後看牛人的結題報告,最後做會了題目,演算法自然就掌握了。重在堅持~~
⑸ 刷題怎麼刷最快
刷題其實只有兩個目的,一是提高熟練度,二是見識新思路,新知識點。
前者是「這道題我會但過程細節不熟所以我做」,後者是「這個類型不太熟所以我做題看看還有哪些遺漏的知識點」。
知道這兩個目的後才能有效的刷題。
1。做哪裡的題目?
作為刷題來說,少做整套試卷多做專題性的總結。二輪復習書是個不錯的選擇因為內容基本上是按知識點分類,這樣做題對鞏固知識點或者查漏補缺有幫助。
2。如何做題?
思考—動筆—對答案—總結。做題前一定要想這道題的「破綻」在哪,考得是哪些知識點,之前做過的某某題跟這個是不是一樣的或是差別在哪裡。這樣的思考可以極大的提高做題效率。如果刷題的目的是前者,按照高考的答題要求每一步每一個計算做完整,對答案看看哪裡可能扣分下回注意;如果目的是後者,大致寫幾部關鍵點,看看答案是不是自己的思路,是就pass。最後總結,這道題的價值在哪?有沒有必要寫到積累本上做專題總結?或者這道題為什麼出錯為什麼沒想到?
3。理化生三門做題有什麼不同?
物理:更注重思維結構,刷題重要的是看「思路」,同一專題的幾種常見解題思路務必總結。
化學:注重專題,如「實驗專題」,「有機專題」等,建議刷題按實驗類型刷,一些細節的操作務必注意總結。
生物:注重細節知識點。生物不建議大量刷題,重在看書掌握知識點 ,做題可為查漏補缺。
⑹ 什麼叫刷題
刷題是一種在短時間內快速接觸大量題目,用盡量短的時間弄懂題目和答案的意思然後解答的方法,它側重於題目的數量而不是完成的質量。
刷題:【shuā tí】
考試通常不會出現很多原題,但是方法思路都是類似的,當刷題量到了一定程度之後,會有一種做題的慣性,當你考試看見類似的題目時,腦海里或多或少都會出現一些思路以及想法(至少大腦不會出現放空狀態了)。
積極刷題,也要積極整理,把自己認為重要的:設題陷阱、答題模板、知識漏洞、課外延伸、應試技巧等整理在本子上,零碎時間翻看、考前翻看,都會有幫助的。整理後你也會發現考試命題的。
刷題的具體操作方法:
1、先規定一定的答題時間,開始計時後開始做答,憑第一直覺在心中給出解題思路把要用到的公式寫出來,不用計算,掐表暫停。
2、看答案,如果答案思路和自己的完全一致,那麼直接跳到下一題。
3、如果答案的思路和自己的不一樣,那麼先記錄下來,等做題時間結束後,只研究做錯了的題目的解題方法。
⑺ 演算法如何刷題
1、原題
我自己感覺原題的概率還是挺大的,特別是劍指offer的66題更是如此。千萬別小看這66題,這幾十道題裡面基本所有的演算法類型都有包括在內,常用的數據結構,操作方式,常用演算法思路都有不少的題。
如果真的能夠充分理解這幾十道題的最優解,我感覺其實已經形成基本的演算法思維了。
另外,leetcode的原題也很常見,因為LC本身題量大,在裡面出原題不是為了考倒你,而是檢驗你的刷題質量。
畢竟那些大公司面試官也不是傻子,知道你在面試前肯定會大規模刷題的。所以把刷過的題完全搞懂才是最重要的。
2、改編題
改編題就很顯而易見了。改編題大多需要從基本的演算法原理中找到處理的思維,然後結合實際題干進行性能優化,就能夠搞定。
這里要記得一點的是,正常的演算法考察不會故意刁難你(正常情況),也不會給過多的時間讓你思考和敲代碼。
所以遇到改編題不要想得太復雜,盡量要找到它的演算法思維是什麼。怎麼說呢,透過現象看本質。我總結的改編題有以下幾種思路:
1)新的數據結構,換湯不換葯。比如最常見的排序演算法的改編,原來是對數字進行排序,現在對鏈表排序等等。比較難一點的可能會遇到自定義的數據結構。但是演算法本質不會變。
2)演算法類型改編。
這里要說的就是一個比較大的范圍,比如動態規劃、貪心演算法、遞歸、回溯和分治等等。這種是從演算法大的類型上進行改編,很難用相同的套路去解題。
遇到這類題的關鍵就是要先弄明白演算法核心。比如動態規劃的狀態方程,貪心演算法的局部最優情況,遞歸回溯的邊界判斷,分治的子問題劃分等等。這種類型的確比較難把握,怎麼碩呢,每種類型的都來搞幾道感覺感覺吧。
3)添加應用題背景。
這種題目看起來不難,但是難就難在對應用題背景的理解,需要去理解題意,然後考慮合適的數據結構和處理演算法。這裡面有數學建模的思維在裡面,需要把一堆無用的信息剔除,篩選出有效的信息,然後才能選擇正確的演算法。
3、創新題
這類題考察的是你的擴展思維,如果說上面的題考查的是你的思維深度,這種題就是考察演算法的廣度。可能一看題目,完全沒見過這種類型。但是演算法本身其實不就是讓計算機代替人腦進行高重復性的計算嘛。
首先你需要想到你應該去怎麼算這個題,然後再換到計算機上,會發生什麼問題(空間時間問題,運行效率,代碼冗餘等等),之後再想通過經典的演算法原理來解決這些
1、題型分類
按照個人的習慣,喜歡按照一種類型狂刷,然後再刷另外一種類型。一般常見的演算法類型可分為:
數組、鏈表
包含基本排序演算法、二分查找、鏈表的一系列操作。
棧、隊列、堆
利用棧、隊列互相實現,堆的使用
二叉樹與圖
主要是遍歷演算法和節點的計算:
二叉樹四種遍歷方式、廣度優先遍歷(BFS)和廣度優先遍歷(DFS),節點到節點距離等等。
哈希表
使用標准庫自帶的模板或者函數就很簡單了,一般會與其它數據結構相結合來提升時間復雜度。
字元串操作
字元串的操作也很多,本質上可以看作是數組的操作。另外字元串的一些匹配和尋求字串的演算法還是非常具有思考價值的。KMP,馬拉車等等。
遞歸
重點掌握邊界判斷條件。
回溯
重點掌握邊界判斷條件。
分治
重點掌握如何劃分子問題。
動態規劃
題太多了,可從一階dp到二階dp理解不同的狀態方程。
貪心及其它
這個就很容易理解了,遇到貪心題應該要偷笑了。
2、高頻熱點多刷
這不多說了吧,Leetcode熱題HOT 100。你值得擁有。
在不知道怎麼刷的情況下,不如先刷起來。刷個題沒那麼多捷徑,只有堅持刷起來了,才會形成自己的思維方式和學習習慣。
我建議是先按照類型刷,每個類型刷十幾二十道。然後打混按照演算法熱度排序重新查漏補缺。
3、思路回顧
許多同學在一股腦刷了很多題之後,再看做過的題會發現忘了不少。可能大家都是這樣的吧。我覺得是因為在刷題的時候過於心急,理解了大概就過了,或者類型做的太雜,沒有留下印象。
我比較喜歡的方式是偶爾會重新看看曾經做過的題,就看題目然後想思路,再畫一畫步驟演進,沒時間就不細敲了。這樣可以增強一下思維記憶,之前理解過的東西,再回憶起來還是非常快的。
⑻ 怎麼循序漸進的學習演算法演算法對於程序員有什麼作用
首先,對於大部分程序員而言,在工作中不是必須的,但是你要找工作,特別是剛畢業參加校招的學生,想進入一些比較大的公司(BAT之流),是必須要學好演算法的。
此外,在提高自我技術水平的過程中,比如去閱讀一些優秀的代碼的時候,也是需要演算法功底的,就像去看leveldb、redis源碼的時候,起碼得知道跳錶是個啥吧,看Linux內核文件系統的代碼得知道紅黑樹是個啥吧。
再就是有一個很重要的影響:演算法學的好的話,不論對你思考問題的方式還是對你編程的思維都會有很大的好處。
另外關於刷題的網站還是首推Leetcode。
如果有一些演算法基礎的話,推薦Codeforces。
至於資料書籍的話,其實沒有太多要求,網上的資料很多,隨便谷歌一下就能找到很多詳細的資料。
演算法導論的話不推薦,不推薦初學者看。這本書是本神書,但是這本書的門檻比較高,需要有一定數學基礎和演算法基礎的人去研究,如果你沒有一定的基礎或者對演算法狂熱的學習興趣,你很難啃下去。
改了一下知識列表的結構,分了下類,可能更加清楚一點。這裡面基礎是我覺得必須應該掌握的,中等的是有如有餘力最好學習的,高級的可以了解,可以了解一下,對於個別感興趣的可以深入學習一下。
⑼ 演算法到底應該怎麼學
刷與不刷ACM ICPC的人在演算法能力上會有巨大差距。
如果真想深入掌握各種演算法,還是先刷題吧。刷到一定境界再去看更高級的演算法書。
不得不承認現實生活中,一般碼農工作對演算法能力要求太低了,這一度讓人們(包括我)認為演算法似乎不那麼重要。其實學習演算法所鍛煉出來的對各種問題敏感的反應和融會貫通能力還是非常重要的。
編程嘛,就是操作數據輸出結果
演算法和數據結構是配套的,你應該掌握的主要內容應該是:
這個問題用什麼演算法和數據結構能更快解決
這就要求你對常見的結構和演算法了熟於心,你不一定要敲代碼,用紙手寫流程是更快的方式。
對你不懂的數據結構,你要去搜它主要拿來幹嘛的,使用場景是什麼。
細節出錯是你對編程語言不熟悉才會導致的問題,跟你懂不懂演算法沒關系,這個你應該多寫寫練手小程序,背代碼是很愚蠢的行為。
其實我覺得你這么迷茫不如實現一下stl的函數好了
我的經驗就是去模擬(當然模擬只限於基礎的演算法)。甚至是手動模擬,比如我之前學深搜,學遞歸,代碼很簡單,但是因為涉及到棧,而你的大腦短時間內存儲的棧深度只有幾層(臨時變數越多你大腦能模擬的棧深度就越少),實際上你沒辦法用大腦去想。比如學習圖的深搜,一開始我是不理解的,對遞歸沒辦法理解。後來我就在紙上模擬出來,建立好鄰接表以後,按照代碼步驟一步步紙筆來模擬,慢慢就知道了代碼的工作過程。你學習快排也是,當然你背代碼也能寫出來,但是可能不理解,很快就忘了。《演算法導論》書上就有比較細致的執行過程,你手動模擬下partition和quicksort的過程,一開始就用很簡單的用例,把整個過程都手動執行一遍,慢慢就了解了。很多演算法都有一個循環不變式,你代碼如果邏輯正確並且能夠維持循環不變式,一般寫出來就是正確的。
建議找本《演算法》或者《演算法導論》這些教材,每學習一個演算法就先大致瀏覽下, 然後細致分析每一步代碼的執行過程(紙筆模擬或者代碼單步調試),當確認你真正明白之後,嘗試不看代碼就靠對演算法過程的了解和正確的邏輯去自己實現。
當然,我不認為你寫出很多演算法就是高手了,現在大部分高級語言不需要你重復造輪子,你造出來的質量也遠遜於庫中那些高手的代碼,可以去學習他們代碼的實現,比如看看stl源碼。真正工程用到的代碼與一般演算法實現還是有很多改進的。
最重要的不是你會寫這些演算法了,而是學會了很多思想。比如二分的思想,遞歸的思想,分治的思想,動態規劃,貪心等,以及現實中很多數據結構的抽象等。難的不是學會了演算法,而是如何運用這些演算法思想去解決問題。
⑽ 做為一個初學者,如何才能學好演算法呢,感覺自己很菜
凡事都講究動機,你學習演算法的目的是什麼呢?目的不同,學法不同側重不同。
如果你是准備跳槽,以面試為目的,可以先從cracking the coding interview入手,題目是按照鏈表,樹圖,遞歸這種章節安排的,每章都有題目,難度適中,第一遍自己寫不出來很正常,畫圖分析,然後再做第二遍,第二遍就快很多,理解也深刻了,實在理解不了的演算法,沒辦法,背吧,說不定到後面不知什麼時候就理解了,所謂讀書百遍,其意自現,演算法也一樣。
如果你是半路出家的程序員,看書覺得看不下去,可以試著看看視頻,現在網路這么發達,網上有很多免費的精品視頻,比如潭州教育老師的數據結構以及清華鄧俊輝老師的數據結構都是特別好的課程。
最後一種就是你對演算法理論和精髓確實感興趣,且有一定的數學功底,你可以嘗試研究下《演算法導論》,甚至《計算機程序設計藝術》(反正我是看不下去)。
其實,無論出於哪種目學習演算法,其實最重要的一點就是:多編程實踐,多思考,這是廢話,但這也是真理。