演算法要怎麼學好?
自學了js語法之後,找了一本《學習Javascript數據結構與演算法》來研習演算法。
看的很懵逼,之後瘋狂上機強記代碼。不過,看到後面的,前面的基本都忘了。
後來,去背演算法的過程描述,情況好了點,至少知道演算法的原理,但自己實現依舊整不出!!
可視化,用形象記憶,用工具看清楚演算法的執行過程,腦子裡生成動態圖景,才能理解演算法原理。
而不是一上來就去死磕演算法的實現代碼(不少傻瓜背代碼,中國的教育所賜),如果你初學就這樣做,磕死自己都沒多大用處。
visualising data structures and algorithms through animation
如果你一時寫不出來演算法的實現,就先把它用熟練,語言里都有常用演算法的封裝,去用這些調用,用不同量級的數據去benchmark不同的實現。
演算法學習是沒有終點的學習,不要假設老子搞定書上寫的那些個就行了,演算法不是拿來面試用的,雖然他在面試的時候很有用。他是一種思維的習慣。
良師
本科的時候買來《演算法導論》來看,大二的時候覺得動歸特別牛,於是一遍一遍的看,看了就忘看了就忘,不禁感嘆這演算法果真牛,看了N多遍都不得其精髓。當時覺得厚厚的一本演算法書真心好厚,感覺內容浩瀚地不得了。
直到有天遇到了卜神(教演算法的一名老師),真心不得不說老師對演算法的理解出神入化,講起來也深入淺出,我等愚鈍之輩醍醐灌頂,豁然開朗。破除了我對演算法望而卻步的心理,也引起了更多的興趣,乃良師也!打算近期整理一下主要的幾種演算法,記錄一下心得,溫故而知新。
我認為良師最贊的一點是:很有體系
如果水平不夠,這是自己看書get不到,或者需要花費很長的時間和很強的理解力才能get到。
鑒於對題主的情況不是很了解,給出以下兩點建議:
- 先學習《數據結構》,如果你沒有學過的話。同時建議用C或C++;
- 然後學習演算法;如果沒有基礎,建議找一個演算法視頻課程帶著看,coursera上應該有很不錯的,比自己看會更有體系。當然你也可以自己學學看,等你學不動了再找視頻教程或許會能達到孔老夫子的「不憤不啟,不悱不發」的效果。
強記代碼學不好演算法的,演算法可以看看 演算法導論這本書
另外用js寫演算法不是一個很好的選擇,建議使用c
謝邀。
我建議先學數據結構,然後學經典的排序-&>樹的結構-&>樹的查找等常用的就行了。然後在學的時候多畫圖,一步一步理解整個代碼流程以及演算法策略問題。不用死記硬背,主要還是靠理解,最好的就是關上書自己實現一次。
首先學習演算法需要了解基本的一個思路,因為計算機的設計沒怎麼變,數據處理的邏輯也比較固定,然後變的那部分就是演算法,大多屬於策略:
1. 輸入的數據
2. 處理中心
這兒就是你演算法的體現,比如 樹的深度查找,具體理解就是不斷往下找,具體代碼實現要看你代碼的把握能力,其實思想很簡單。
3. 輸出你想要的數據
然後這個是計算機最基礎的模型。
主要的是我說了這麼多,可能你還是覺得,這等於沒說,那麼我們來談下方法。
1. 建立常見數據格式的熟悉度,其實大多應該是屬於數據結構裡面的,演算法和數據結構可以分開理解,最後才能綜合使用。
(1) Stack
(2) Queue
(3) Tree
(4) Table
(5) LinkedList
- 理解每一種數據結構的特性,比如隊列的先進先出,棧的先進後出。
- 理解每一種結構的存儲形式,對這些存儲形式進行抽象到具象的認識,比如:Stack 和 Queue 在沒變種之前我是否可以簡單理解成編程的 Array ,只不過是取數據的方式不同,可以看一下我博客的這篇:
http://60sky.com/post/love-code.html
- 理解每種數據結構之間的差異性和共同點,比如 Tree 結構和圖結構的數據不同的地方,比如可以理解成樹是圖的一個簡單結構,離散數據和連續的數據在結構的表現上也可以千變萬化。
- 理解計算機的遞歸和循環,這個很重要,要認真理解。
2. 理解完數據結構後咋們才來看演算法,演算法基本可以理解成對這些數據結構的利用,然後組織這些結構,讓計算機按我們處理代碼的順序產出預期數據的過程。
(1) 排序
(2) 查找
(3) 遍歷
=&> 基本的就這些,那麼為什麼有演算法難度,比如 O(1), O(n), O(n^2) 這種的差異呢?
這個就體現在:
(1) 輸入數據的量和結構
(2) 對量的處理,對結構的重組
(3) 處理過程,計算機是否友好,因為可能因為效率而犧牲可讀性
(4) 處理完了之後的結構存儲是否下次好用,你是注重讀取效率還是修改效率
3. 動手實現一些基本演算法,上來不要一口吃成胖子。
每一種處理方式對數據結構的利用,每一種數據結構更適合在哪些策略中進行處理。
說多了也好像不起撒作用,還是多練習吧,先提高對語言的熟悉度,如果你語言都不熟悉的話,會在你寫演算法的時候產生蛋痛的地方。對於同一個智商等級的程序員,基本演算法是可以靠努力的哈,加油!
對了,第一次學演算法最好找個有指針的學習~還有就是有圖有理論的,不要先看代碼。比如 C 語言的大學教材和 Java 其實都還行,Java 封裝度有點高,不過對理解思路還不錯。
別一上來就寫代碼。
我覺得用代碼實現一個演算法只是演算法裡面佔比不大的一部分。
研究演算法,數據結構先搞清楚,演算法依賴於數據結構。
對於那些經典的常用的演算法在腦海里要有個動態實現的過程。
我在刷Leetcode的時候,經常有種感覺,一旦腦子裡有了演算法實現的過程,或者說設計好了演算法,代碼也就呼之欲出了。
如果知道原理代碼還寫不出來,很有可能是最基本的數據結構沒過關。
數據結構和演算法入門我推薦《演算法競賽入門經典》和王道論壇出的那本考研復慣用的數據結構。
用背的方式,肯定不對。
理解+敲代碼。
這個問題跟怎麼學好數學一樣一樣的,來,跟我念三遍:刷題!刷題!刷題!
不要用web語言學習演算法,使用接近馮氏計算機體系的語言模型
學習演算法首先要明確演算法是用來幹什麼的,然後循序漸進,要勇於實踐。
1,能實現。演算法首先是讓計算機可以計算給定的問題。所以演算法首先要給定數據結構,學習並熟練掌握常用結構的操作是必須的:棧,鏈表,樹,圖等。在此基礎上能自如用遞歸寫程序,掌握回塑法和分支限界法,無論程序有多慢,先能寫出來,遍歷所有解的空間。這是第一步目標。
2,快實現。在能寫出可用程序的基礎上,學習程序時間複雜度和空間複雜度的知識寫更好更快的演算法,如動態規劃等。這是第二步。
3,又快又好的實現。大多數好的演算法為了快速得到結果會降低對質量的要求,也就是啟發式演算法,如聚類中的貪婪法,序列比對中的BLAST等。更多的要用統計方法,機器學習等等需要同時對演算法質量和速度進行評估。這是第三步。
學無止境,問題導向,實踐為先。走出代碼堆,演算法天地寬。一邊刷題一邊學,leetcode上題都帶tag的,而且比較簡單,做不出來就去看高票答案,一定要看懂,很多演算法實現都是有固定模版或思路的。
首先學好數據結構,我個人認為學數據結構要「降維」思考…無論是一棵樹還是一張圖最後在計算機內存里那些數據都是以一條線存在的;
其次基本的數學功底要有至少積分以及求和要會;第三不要用js 不要用js 不要用js……雖然我現在工作主要使用Node但是用C或者C++更能讓你對計算機的底層更加有概念,對你有好處OI狗強答一發,對象是把演算法當做一門「技術」而非科學的程序員。
對於大多數經典演算法來說,其思想都是簡單和直觀的。因此關鍵之處就在於理解演算法的本質。這一點上可以通過打代碼輔助理解,也可以手推,總之就是要理解其基本原理。如果要把演算法當做技術而非科學,對於證明部分可以略過,僅在必要時輔助理解。
順便同意先學數據結構再學高級演算法(按照算導的說法,也就是dp和貪心這類)的觀點。因為數據結構比起dp之流還是更直觀一點。
另外,作為一門技術,必要的練習是免不了的。這包括兩個部分,一個是數學技巧的練習,一個是代碼能力的練習。前者參考《演算法導論》,《具體數學》之類,後者參見poj, hdu, bzoj等各大oj。推薦閱讀:
※類似git/linux的文件對比功能(diff)是怎麼實現的?
※關於計算機的一切,有可稱靈性的東西嗎?
※怎麼理解kmp演算法中的next數組?
※最簡便的找字元串中最長迴文子串的方法是什麼?
※在NOIP競賽中如何通過數據範圍估計演算法複雜度,選取適合的演算法?
TAG:JavaScript | 演算法 |