刷演算法題靠背
㈠ 做為一個初學者,如何才能學好演算法呢,感覺自己很菜
凡事都講究動機,你學習演算法的目的是什麼呢?目的不同,學法不同側重不同。
如果你是准備跳槽,以面試為目的,可以先從cracking the coding interview入手,題目是按照鏈表,樹圖,遞歸這種章節安排的,每章都有題目,難度適中,第一遍自己寫不出來很正常,畫圖分析,然後再做第二遍,第二遍就快很多,理解也深刻了,實在理解不了的演算法,沒辦法,背吧,說不定到後面不知什麼時候就理解了,所謂讀書百遍,其意自現,演算法也一樣。
如果你是半路出家的程序員,看書覺得看不下去,可以試著看看視頻,現在網路這么發達,網上有很多免費的精品視頻,比如潭州教育老師的數據結構以及清華鄧俊輝老師的數據結構都是特別好的課程。
最後一種就是你對演算法理論和精髓確實感興趣,且有一定的數學功底,你可以嘗試研究下《演算法導論》,甚至《計算機程序設計藝術》(反正我是看不下去)。
其實,無論出於哪種目學習演算法,其實最重要的一點就是:多編程實踐,多思考,這是廢話,但這也是真理。
㈡ 演算法如何刷題
1、原題
我自己感覺原題的概率還是挺大的,特別是劍指offer的66題更是如此。千萬別小看這66題,這幾十道題裡面基本所有的演算法類型都有包括在內,常用的數據結構,操作方式,常用演算法思路都有不少的題。
如果真的能夠充分理解這幾十道題的最優解,我感覺其實已經形成基本的演算法思維了。
另外,leetcode的原題也很常見,因為LC本身題量大,在裡面出原題不是為了考倒你,而是檢驗你的刷題質量。
畢竟那些大公司面試官也不是傻子,知道你在面試前肯定會大規模刷題的。所以把刷過的題完全搞懂才是最重要的。
2、改編題
改編題就很顯而易見了。改編題大多需要從基本的演算法原理中找到處理的思維,然後結合實際題干進行性能優化,就能夠搞定。
這里要記得一點的是,正常的演算法考察不會故意刁難你(正常情況),也不會給過多的時間讓你思考和敲代碼。
所以遇到改編題不要想得太復雜,盡量要找到它的演算法思維是什麼。怎麼說呢,透過現象看本質。我總結的改編題有以下幾種思路:
1)新的數據結構,換湯不換葯。比如最常見的排序演算法的改編,原來是對數字進行排序,現在對鏈表排序等等。比較難一點的可能會遇到自定義的數據結構。但是演算法本質不會變。
2)演算法類型改編。
這里要說的就是一個比較大的范圍,比如動態規劃、貪心演算法、遞歸、回溯和分治等等。這種是從演算法大的類型上進行改編,很難用相同的套路去解題。
遇到這類題的關鍵就是要先弄明白演算法核心。比如動態規劃的狀態方程,貪心演算法的局部最優情況,遞歸回溯的邊界判斷,分治的子問題劃分等等。這種類型的確比較難把握,怎麼碩呢,每種類型的都來搞幾道感覺感覺吧。
3)添加應用題背景。
這種題目看起來不難,但是難就難在對應用題背景的理解,需要去理解題意,然後考慮合適的數據結構和處理演算法。這裡面有數學建模的思維在裡面,需要把一堆無用的信息剔除,篩選出有效的信息,然後才能選擇正確的演算法。
3、創新題
這類題考察的是你的擴展思維,如果說上面的題考查的是你的思維深度,這種題就是考察演算法的廣度。可能一看題目,完全沒見過這種類型。但是演算法本身其實不就是讓計算機代替人腦進行高重復性的計算嘛。
首先你需要想到你應該去怎麼算這個題,然後再換到計算機上,會發生什麼問題(空間時間問題,運行效率,代碼冗餘等等),之後再想通過經典的演算法原理來解決這些
1、題型分類
按照個人的習慣,喜歡按照一種類型狂刷,然後再刷另外一種類型。一般常見的演算法類型可分為:
數組、鏈表
包含基本排序演算法、二分查找、鏈表的一系列操作。
棧、隊列、堆
利用棧、隊列互相實現,堆的使用
二叉樹與圖
主要是遍歷演算法和節點的計算:
二叉樹四種遍歷方式、廣度優先遍歷(BFS)和廣度優先遍歷(DFS),節點到節點距離等等。
哈希表
使用標准庫自帶的模板或者函數就很簡單了,一般會與其它數據結構相結合來提升時間復雜度。
字元串操作
字元串的操作也很多,本質上可以看作是數組的操作。另外字元串的一些匹配和尋求字串的演算法還是非常具有思考價值的。KMP,馬拉車等等。
遞歸
重點掌握邊界判斷條件。
回溯
重點掌握邊界判斷條件。
分治
重點掌握如何劃分子問題。
動態規劃
題太多了,可從一階dp到二階dp理解不同的狀態方程。
貪心及其它
這個就很容易理解了,遇到貪心題應該要偷笑了。
2、高頻熱點多刷
這不多說了吧,Leetcode熱題HOT 100。你值得擁有。
在不知道怎麼刷的情況下,不如先刷起來。刷個題沒那麼多捷徑,只有堅持刷起來了,才會形成自己的思維方式和學習習慣。
我建議是先按照類型刷,每個類型刷十幾二十道。然後打混按照演算法熱度排序重新查漏補缺。
3、思路回顧
許多同學在一股腦刷了很多題之後,再看做過的題會發現忘了不少。可能大家都是這樣的吧。我覺得是因為在刷題的時候過於心急,理解了大概就過了,或者類型做的太雜,沒有留下印象。
我比較喜歡的方式是偶爾會重新看看曾經做過的題,就看題目然後想思路,再畫一畫步驟演進,沒時間就不細敲了。這樣可以增強一下思維記憶,之前理解過的東西,再回憶起來還是非常快的。
㈢ 比較好的python刷題軟體有哪些
如果是想刷演算法題,那麼還是推薦刷LeetCode。
發展歷程
自從20世紀90年代初Python語言誕生至今,它已被逐漸廣泛應用於系統管理任務的處理和Web編程。
1995 年,Guido van Rossum 在弗吉尼亞州的國家創新研究公司(CNRI)繼續他在 Python 上的工作,並在那裡發布了該軟體的多個版本。
2000 年五月,Guido van Rossum和 Python 核心開發團隊轉到 BeOpen.com 並組建了 BeOpen PythonLabs 團隊。 同年十月,BeOpen PythonLabs 團隊轉到 Digital Creations (現為 Zope Corporation)。
2001 年,Python 軟體基金會 (PSF) 成立,這是一個專為擁有 Python 相關知識產權而創建的非營利組織。 Zope Corporation 現在是 PSF 的贊助成員。
Python的創始人為荷蘭人吉多·范羅蘇姆(Guido van Rossum)。1989年聖誕節期間,在阿姆斯特丹,Guido為了打發聖誕節的無趣,決心開發一個新的腳本解釋程序,作為ABC語言的一種繼承。
之所以選中Python(大蟒蛇的意思)作為該編程語言的名字,是取自英國20世紀70年代首播的電視喜劇《蒙提·派森的飛行馬戲團》(Monty Python's Flying Circus)。
㈣ 前端演算法入門:刷演算法題常用的 JS 基礎掃盲
此篇屬於前端演算法入門系列的第一篇,主要介紹常用的 數組方法 、 字元串方法 、 遍歷方法 、 高階函數 、 正則表達式 以及相關 數學知識 。
在尾部追加,類似於壓棧,原數組會變。
在尾部彈出,類似於出棧,原數組會變。數組的 push & pop 可以模擬常見數據結構之一:棧。
在頭部壓入數據,類似於入隊,原數組會變。
在頭部彈出數據,原數組會變。數組的 push (入隊) & shift (出隊) 可以模擬常見數據結構之一:隊列。
concat 會在當前數組尾部拼接傳入的數組,然後返回一個新數組,原數組不變。
在數組中尋找該值,找到則返回其下標,找不到則返回 -1 。
在數組中尋找該值,找到則返回 true ,找不到則返回 false 。
將數組轉化成字元串,並返回該字元串,不傳值則默認逗號隔開,原數組不變。
翻轉原數組,並返回已完成翻轉的數組,原數組改變。
從 start 開始截取到 end ,但是不包括 end
可參考 MDN:Sort [5]
將數組轉化成字元串,並返回該字元串,逗號隔開,原數組不變。
返回指定索引位置處的字元。類似於數組用中括弧獲取相應下標位置的數據。
類似數組的concat(),用來返回一個合並拼接兩個或兩個以上字元串。原字元串不變。
indexOf ,返回一個字元在字元串中首次出現的位置, lastIndexOf 返回一個字元在字元串中最後一次出現的位置。
提取字元串的片斷,並把提取的字元串作為新的字元串返回出來。原字元串不變。
使用指定的分隔符將一個字元串拆分為多個子字元串數組並返回,原字元串不變。
match() 方法可在字元串內檢索指定的值,或找到一個或多個正則表達式的匹配,並返回一個包含該搜索結果的數組。
注意事項 :如果 match 方法沒有找到匹配,將返回 null 。如果找到匹配,則 match 方法會把匹配到以數組形式返回,如果正則規則未設置全局修飾符 g ,則 match 方法返回的數組有兩個特性: input 和 index 。 input 屬性包含整個被搜索的字元串。 index 屬性包含了在整個被搜索字元串中匹配的子字元串的位置。
replace 接收兩個參數,參數一是需要替換掉的字元或者一個正則的匹配規則,參數二,需要替換進去的字元,仔實際的原理當中,參數二,你可以換成一個回調函數。
在目標字元串中搜索與正則規則相匹配的字元,搜索到,則返回第一個匹配項在目標字元串當中的位置,沒有搜索到則返回一個 -1 。
toLowerCase 把字母轉換成小寫, toUpperCase() 則是把字母轉換成大寫。
includes 、 startsWith 、 endsWith , es6 的新增方法, includes 用來檢測目標字元串對象是否包含某個字元,返回一個布爾值, startsWith 用來檢測當前字元是否是目標字元串的起始部分,相對的 endwith 是用來檢測是否是目標字元串的結尾部分。
返回一個新的字元串對象,新字元串等於重復了指定次數的原始字元串。接收一個參數,就是指定重復的次數。原字元串不變。
最常用的 for 循環,經常用的數組遍歷,也可以遍歷字元串。
while 、 do while 主要的功能是,當滿足 while 後邊所跟的條件時,來執行相關業務。這兩個的區別是, while 會先判斷是否滿足條件,然後再去執行花括弧裡面的任務,而 do while 則是先執行一次花括弧中的任務,再去執行 while 條件,判斷下次還是否再去執行 do 裡面的操作。也就是說 do while 至少會執行一次操作 .
拷貝一份遍歷原數組。
for…of 是 ES6 新增的方法,但是 for…of 不能去遍歷普通的對象,** for…of 的好處是可以使用 break 跳出循環。**
面試官:說一下 for...in 和 for...of 區別?
返回一個布爾值 。當我們需要判定數組中的元素是否滿足某些條件時,可以使用 every / some 。這兩個的區別是, every 會去判斷判斷數組中的每一項,而 some 則是當某一項滿足條件時返回。
rece 從左到右將數組元素做「疊加」處理,返回一個值。 receRight 從右到左。
Object.keys 方法的參數是一個對象,返回一個數組。該數組的成員都是該對象自身的(而不是繼承的)所有屬性名,且只返回可枚舉的屬性。
Object.getOwnPropertyNames 方法與 Object.keys 類似,也是接受一個對象作為參數,返回一個數組,包含了該對象自身的所有屬性名。但它能返回不可枚舉的屬性。
這里羅列一些我在刷演算法題中遇到的正則表達式,如果有時間可認真學一下 正則表達式不要背 [7] 。
持續更新,敬請期待……
若一個正整數無法被除了 1 和它自身之外的任何自然數整除,則稱該數為質數(或素數),否則稱該正整數為合數。
㈤ 公基靠背還是刷題
公基在背的同時結合刷題效果更好。
事業單位考的公基全稱公共基礎知識,是一門綜合性考試,內容涵蓋了政治、經濟、法律、管理、脊唯科技、歷史、語文基礎與公文寫作等諸多方面。
具體的考試內容包括:馬克思主義哲學原理、毛概、國家機關工作人員的職業道德、法律凱頌知識、語文基礎知識和公文寫作、經濟知識和科技知識、歷史知識、最新的時政知識等。
㈥ 演算法題套路總結(三)——動態規劃
前兩篇我總結了鏈表和二分查找題目的一些套路,這篇文章來講講動態規劃。動態規劃從我高中開始參加NOIP起就一直是令我比較害怕的題型,除了能一眼看出來轉移方程的題目,大部分動態規劃都不太會做。加上後來ACM更為令人頭禿的動態規劃,很多題解看了之後,我根本就不相信自己能夠想出來這種解法,看著大佬們談笑間還加一些常數優化,一度懷疑自己的智商。以前一直覺得動態規劃是給大佬准備的,所以刻意地沒有去攻克它,主要也是沒有信心。但是後來慢慢的,我再做LC的時候,發現很多DP的題目我自己慢慢能夠推出轉移方程了,而且似乎也沒那麼難。我一直在思考,到底是我變強了,還是因為LC的題目相比ACM或者NOI太簡單了。其實主要還是後者,但是同時我也發現,動態規劃其實是有套路的,我以前方法不對,總結太少。
主要就是,站在出題人的角度,他幾乎不太可能完全憑空想出一個新的DP模型,因為動態規劃畢竟要滿足:
因此,能夠利用DP來解決的問題實際上是有限的,大部分題目都是針對現有的模型的一些變種,改改題目描述,或者加點限制條件。所以要想攻克DP題目,最根本的就是要充分理解幾個常見的DP模型。而要充分理解常見經典DP模型,就需要通過大量的做題和總結,而且二者不可偏廢。通過做題進行思考和量的積累,通過總結加深理解和融會貫通進而完成質的提升。
動態規劃是求解一個最優化問題,而最核心的思想就是:
解一道DP題目,先問自己幾個問題:
當然以上內容看起來比較抽象,雖然它深刻地揭露了動態規劃的本質,但是如果臨場要去想明白這些問題,還是有些難度。如果只是針對比賽和面試,就像前面說的,DP題型是有限的。只要刷的題目足夠多,總結出幾個經典模型,剩下的都是些變種+優化而已。
一般來說,動態規劃可以分成4個大類:
線性DP就是階段非常線性直觀的模型,比如:最長(上升|下降)序列,最長公共子序列(LCS)等,也有一些簡單的遞推,甚至都算不上是 經典模型 。
最長上升序列是一個非常經典的線性模型。說它是個模型,是因為它是一類題的代表,很多題目都只是換個說法,或者要求在這基礎上進一步優化而已。最長上升序列最基礎的轉移方程就是 f[i] = max{f[j]}+1 (a[i] > a[j]) , f[i] 表示一定要以 a[i] 結尾的序列,最長長度是多少。很顯然就是在前面找到一個最大的 f[j] 同時滿足 a[j]<a[i] 。因此是 N^2 的時間復雜度和N的空間復雜度。這種方法是最樸素直觀的,一定要理解。它非常簡單,因此很少有題目直接能夠這么做。大部分相關題目需要進一步優化,也就是有名的單調隊列優化,能夠把復雜度優化到nlogn。
說單調隊列優化之前必須明白一個貪心策略。因為要求的是最長上升序列,那麼很顯然長度為k的上升序列的最大值(最後一個數)越小越好,這樣後面的數才有更大的概率比它大。如果我們記錄下來不同長度的上升序列的最後一個數能達到的最小值,那麼對於後續每個數t,它要麼能放到某個長度為y的序列之後,組成長度為y+1的上升序列,要麼放到某個長度為x的序列後面,把長度為x+1的序列的最大值替換成t。同時我們可以發現,如果x<y,那麼長度為x序列的最後一個數一定比長度為y的序列最後一個數小。因此這個上升序列我們可以用一個數組來維護(所謂的單調隊列),數組下標就代表序列長度。 opt[i]=t 表示長度為i的上升序列最後一個數最小是t。那麼當我們在面對後續某個數x時,可以對單調隊列opt進行二分,把它插到對應的位置。因此總體復雜度就是NlogN。
相關題目比如:
但是你可以發現,其實這個題型其實變種很有限,吃透了也就那麼回事。所以一定要總結。
最長公共子序列也是線性DP中的一種比較常見的模型。說它是一種「模型」其實有點拔高了,其實它就是一類比較常見的題目。很多題目都是在LCS的基礎上進行簡單的擴展,或者僅僅就是換一個說法而已。
求兩個數組的最長公共子序列,最直觀地做法就是:設f[i][j]表示S[..i]和T[..j]的最長公共子序列,則有:
這個轉移方程也非常好理解,時間復雜度是 N^2 ,空間復雜度也是 N^2 。不過仔細觀察你可以發現,當我們計算第i行時只與i-1和i行有關。因此我們可以利用01滾動來優化空間復雜度為2N。
相關題目:
線性DP除了上述的兩種常見題型,還有很多別的類型,包括背包。我們要努力去嘗試理解這些題目的異同,它們的轉移方程,以及思路,可能的變化,這樣才能更好的應對未知的題目。以下是一些我總結的題型:
最終結果就是max(0, f[n][2]+f[n][4])。
不過實際上你可以發現,由於各個狀態只和前一維有關,且只能由固定的一個狀態轉移過來,因此我們可以省掉一維,只用4個變數來存儲:
剩下的,同123題類似,由於最多進行k次交易,那麼一天就有2k個狀態:第1次買/賣……第k次買/賣,結合123題的優化,我們只需要2k個變數就能存儲這些狀態。因此設f[i×2]為第i次買入的最優值,f[i×2+1]為第i次賣出的最優值:
以上都是對一些常見的線性DP的一些小結,實際上線性DP還有一個重要的題型就是背包。關於背包,有很多相關的講解,我這里就不多說了,推薦大家看看 背包九講 。下一章依然是DP專題,我講總結一些區間DP的題型。大部分區間DP都是hard級的,對於希望提高自己水平的人來說,需要投入更多精力去理解。
㈦ 秋招筆試演算法題不會做還怎麼辦
可以通過不斷地思考,總結,歸納,不斷刷題來提高自己演算法題的水平,沒有什麼困難的,你需要盡力去學習,祝取得好成績。
如何提高學習效率
時間長並不一定有用,問題的關鍵是:你的單位時間內的學習效率有多高!看著同學們一天到晚都在學習,但為什麼效果不佳?這是一個學習中的老大難問題,也是最令家長、老師、學生感到困惑的問題。解答這個問題的鑰匙就是利用效率法則——高效利用時間,提高學習效率。
在伏爾泰的作品中曾經提到過一個謎語:「世界上有一樣東西,它是最長的也是最短的,它是最快的也是最慢的,它最不受重視但卻又最受惋惜。
沒有它,什麼事也無法完成,這樣的東西可以使你渺小的消滅,你偉大的永續不絕。善於利用時間學習中,不僅要懂得珍惜時間,更要學會運籌時間,使自己在最短的時間內,得到最大的學習效合理分配精力在學習中。
學會排除干擾在學習中,來自外界和自身的一些干擾都會影響你的學習效率,你必須要學會排除和隔離這些學習中的消極因素,將它們的負面效應降到最低你想到這樣唯一的東西是什麼了嗎?沒錯,它就是時間。
學習是在時間中進行的。無可置疑,誰能擁有更多的時間,誰就能獲得更多的知識。長久以來,人們一直在探索怎樣勒住時間的韁繩,以增強自己利用時間的能力。掌握一些高效利用時間的方法,如優化事序、最佳安排、排除干擾等方法能使你的有效學習時間比別人多很多倍。
㈧ 公基知識點很多,刷題和背書哪個方法更好用
首大祥先呢,知識點很多的話,那你就需侍陵要背書和刷題結合起來也不是說哪個方法更好用你只選擇其一呢?那肯定是不行的。你老仿戚可以趁早上的時候或者你什麼時候狀態最好的時候去背書,然後做題主要是鞏固的作用使你記得更牢固。也不能說一味的,只刷題或者一味的只背書那也不行。