刷了 1000 多道算法題,一點(diǎn)心得
大家好,我是魚皮,今天分享一下自己刷算法題目的經(jīng)驗(yàn)。
建議大家先看 UP 今天發(fā)的最新視頻,本文為文字版:

程序員為啥要刷算法?
因?yàn)?“卷啊”!
開個(gè)玩笑,其實(shí),算法題目已經(jīng)成為了公司篩人的一種方式,大廠的每一輪面試基本都會(huì)有幾道算法題,甚至有的公司筆試全部都是算法題。其他題目答的都差不多,那你算法題做不出來,可能就被淘汰了。
所以為啥要刷算法題呢?一方面是幫助你學(xué)習(xí)和理解算法,但另一方面也是像背公式、背八股文一樣,增加你面試時(shí)碰到原題的概率。我刷了 1000 多道題嘛,不夸張的說,在面試的時(shí)候 80% 的算法題都是原題。
當(dāng)然,每個(gè)人學(xué)算法、刷題的目標(biāo)是不同的,首先 要明確你的目標(biāo),因?yàn)槟繕?biāo)不同,刷算法的平臺(tái)和方法也不同。
常見的目標(biāo)有以下四種:
學(xué)習(xí)基本編程語法和思想
想找大廠工作,應(yīng)對面試
算法競賽
鍛煉自己的思維
大部分同學(xué)的目標(biāo)應(yīng)該都是第二個(gè)?,F(xiàn)在的程序員面試中,算法題目基本是必問的,所以,為了找到一份不錯(cuò)的工作,越來越多的同學(xué)意識到了刷算法的重要性,甚至有一些同學(xué)剛開始學(xué)編程,編程語言用的還不熟悉,就想著要提前刷算法準(zhǔn)備起來了。
先聊聊編程新手應(yīng)該怎么刷題吧?
編程新手刷題
對于大一同學(xué),大部分都是剛開始接觸編程,所以刷題的目標(biāo)應(yīng)該更傾向于第一種,即幫助自己學(xué)習(xí)編程。
LeetCode 確實(shí)是如今最火爆的算法刷題平臺(tái),但有一個(gè)很大的誤區(qū)就是一上來就刷 LeetCode,對于編程小白來說,基礎(chǔ)的編程語法、函數(shù)、面向?qū)ο蠖歼€不會(huì)呢,刷什么 LeetCode?學(xué)什么數(shù)據(jù)結(jié)構(gòu)和算法!?
如果基本的編程語法還不熟悉,我建議老老實(shí)實(shí)地做一些 基礎(chǔ)練習(xí)題,應(yīng)該大部分學(xué)校的老師都會(huì)布置課堂作業(yè)吧?
比如我大一的時(shí)候基本就是在刷老師留的 OJ(Online Judge 在線判題平臺(tái))作業(yè)題目,不同于清華北大等一系列名校的 OJ,我們當(dāng)時(shí)刷的題都比較簡單,每道題目都是解決一個(gè)小問題,比如用 C++ 的 new class 來造汽車。目的是幫助同學(xué)們學(xué)習(xí) C 語言、C++、Java 等基礎(chǔ)語法,熟悉面向?qū)ο缶幊趟枷?,所以比較容易上手。
可能有同學(xué)覺得作業(yè)比較難對吧,其實(shí)學(xué)校布置的課堂作業(yè)大部分都很基礎(chǔ)很基礎(chǔ),如果這都覺得難,我認(rèn)為比起嘗試網(wǎng)上的專業(yè)算法刷題平臺(tái),倒不如踏踏實(shí)實(shí)先把簡單的作業(yè)題啃透和理解。
這里我推薦 PTA 程序設(shè)計(jì)類實(shí)驗(yàn)輔助教學(xué)平臺(tái),上面提供了不少適合新手入門的簡單練習(xí)題,比如基礎(chǔ)編程題目集、浙大版《C語言程序設(shè)計(jì)(第3版)》題目集等。
網(wǎng)址:https://pintia.cn/

如果你已經(jīng)能夠使用一門編程語言開發(fā)簡單的程序了,那就要 確定自己的下一個(gè)目標(biāo),為了通過面試刷算法?還是想挑戰(zhàn)自我,參加競賽呢?
下面我針對不同的目標(biāo),來分別推薦一些資源。
找工作刷題
現(xiàn)在大廠面試基本每一輪都會(huì)考幾道算法題目,因此,越來越多的小伙伴意識到刷題的重要性。
其實(shí),不需要關(guān)心太多平臺(tái),找工作刷題,選擇 LeetCode 就夠了,國內(nèi)最全的算法刷題網(wǎng)站。
地址:https://leetcode-cn.com/
很多朋友剛開始刷 LeetCode 可能都會(huì)懷疑自己的智商,比如我。
我是一名計(jì)算機(jī)專業(yè)的學(xué)生,并且大一時(shí)還做過一些 ACM 題目,水到過一些小的比賽獎(jiǎng)項(xiàng),但是初次接觸 Leetcode 時(shí)感覺仍然像是走進(jìn)了一個(gè)船新的世界,感覺上面的題目自己無從下手。

后來和別人交流才發(fā)現(xiàn),原來我不是一個(gè)人,一頭霧水才是剛開始刷 Leetcode 的正常情況!
不過當(dāng)我找到了訣竅后,漸漸發(fā)現(xiàn) Leetcode 也沒有那么恐怖。我是從大二開始刷算法的,每天堅(jiān)持留 2 個(gè)小時(shí),刷 2-3 道題目,大概過了一年,面試中的算法題目基本都可以迎刃而解!也幫助我拿到了一些大廠的 offer,最后入職鵝廠。
我總共刷了 1000 多道算法題目,光在 Leetcode 上就有 600 多道(簡單、中等各占一半),還刷了一些其他平臺(tái)或書籍上應(yīng)對面試的題目,比如《劍指 offer》、???、PAT 等,也都不錯(cuò)。

刷了這么多道題目后,明顯感覺自己的思維能力有了很大的提升,感覺 Leetcode 好像也沒那么難了。
回想最初被 Leetcode 搞到懷疑人生,還是自己沒有找對方法吧~
所以下面簡單地分享下自己刷 LeetCode 的小技巧,希望大家少走彎路。
1. 刷題順序
記住三個(gè)要點(diǎn):從【學(xué)習(xí)板塊 LeetBook】刷起,從【簡單的】刷起,從【通過率高】的刷起!
LeetBook 是 LeetCode 精心整理的算法和數(shù)據(jù)結(jié)構(gòu)專項(xiàng)練習(xí)(以前叫探索,爺青結(jié)),每個(gè)專項(xiàng)對應(yīng)一個(gè)重要的知識點(diǎn),并通過一系列相關(guān)的題目帶大家入門,相對自己零散地選題目來說,更加簡單實(shí)用,還附有講解,是入門的不二之選。
像面試無非就那么幾個(gè)重點(diǎn):樹、動(dòng)態(tài)規(guī)劃、深度 / 廣度優(yōu)先搜索、鏈表、數(shù)組、排序、棧、隊(duì)列、哈希、字符串等。你要先完成專項(xiàng)練習(xí)中一些簡單的題目,理解其背后的算法和數(shù)據(jù)結(jié)構(gòu)。之后,再舉一反三,練習(xí)更多相關(guān)的題目,當(dāng)你能做到用同一個(gè)算法解決一類共性問題,做到 多題一解 時(shí),才算是真正理解了。

地址:https://leetcode-cn.com/leetbook/
刷完 Leetbook 專欄后,進(jìn)入題庫,利用 LeetCode 自帶的題目篩選和排序功能,能夠幫助我們由簡單到中等再到困難,漸進(jìn)式刷題。一般來說,先刷通過率較高的題目,相對比較容易。

2. 利用題解
LeetCode 的每道題目都有很多小伙伴給出了題解,講述如何解決這道題。
怎么才算利用題解呢?
首先,讀題解包括兩個(gè)部分,讀思路 和 讀代碼,既要理解作者做題的思路和邏輯,也要細(xì)致入微地學(xué)習(xí)他人代碼中優(yōu)秀的寫法。即使這道題目你做出來了,擊敗 100% 了,我也建議去看看別人的題解,學(xué)習(xí)更多他人解題的思路,幫助自己打開腦洞,做到 一題多解。
除了 LeetCode 自帶的題解之外,網(wǎng)上有很多其他大佬整理的算法題解,各種編程語言的都有!
比如全網(wǎng)瘋傳的谷歌大佬算法刷題筆記(C++ 語言):

還有 Go 語言的算法題解:

還有《數(shù)據(jù)結(jié)構(gòu) Java 語言描述》:

以上資源都整理到我開發(fā)的【編程導(dǎo)航】中了,可在線免費(fèi)閱讀!
地址:https://www.code-nav.cn
話說,現(xiàn)在網(wǎng)上的題解實(shí)在是太多啦!在刷題時(shí),讀個(gè)一兩份就行了,別給自己太大壓力。
除了看題解外,很多同學(xué)沒有意識到,多寫題解 才是真正的法寶,把自己的解題思路整理成文,或者講給別人聽。這樣做不僅能夠加深自己對題目的印象,進(jìn)一步加深對算法的理解,幫助自己回顧解題過程,從而在面試的時(shí)候更容易復(fù)述;還能幫助到更多同學(xué)。
甚至有一些厲害的同學(xué)通過記錄和分享自己的題解,還沒畢業(yè),就已經(jīng)出版了自己的書籍,年入幾十萬或者百萬!

哎嘿,我才發(fā)現(xiàn)自己當(dāng)年寫的一些題解閱讀量也破千了,爺青回?。?/p>
3. 精益求精
當(dāng)你每次成功解題時(shí),LeetCode 系統(tǒng)會(huì)生成一份解題報(bào)告,告訴你的程序在時(shí)間和空間上擊敗了多少用戶。
雖然答出題目就已經(jīng)很棒了,但還不夠。面試的時(shí)候,一些面試官就喜歡給你出題目的變種,或者要求你用更優(yōu)的方式解出題目。所以,在保證完全理解題目解法的基礎(chǔ)上,請不斷優(yōu)化你的代碼,找到更多的思路和更優(yōu)解,直到擊敗 100% 的用戶吧。
我們在工作中,雖然未必會(huì)直接和算法打交道,但學(xué)習(xí)算法對工作的幫助真的很大!
解算法題時(shí),我們要對多種算法分析復(fù)雜度,從中選擇最優(yōu)解。而在工作中,也是如此,一個(gè)需求有很多種實(shí)現(xiàn)方式,經(jīng)常也要設(shè)計(jì)幾種不同的方案,分析他們的成本、性能等差異,選擇其中最好的一種進(jìn)行實(shí)施。
所以,請認(rèn)真對待每一道算法題目,把它當(dāng)成一個(gè)工程問題來解決,相信你的思維會(huì)逐漸打開,并逐漸掌握編寫高性能程序的技巧。
4. 參與競賽
我建議大家多參加算法競賽,這里的競賽不是指 ACM 區(qū)域賽那種大神級別的,別忘了此時(shí)我們的目標(biāo)只是找工作。
其實(shí),LeetCode、??偷染W(wǎng)站每周都會(huì)開展一次線上算法競賽,看看誰能在有限時(shí)間內(nèi)最快最多地解題。

在競賽的過程中,緊張刺激的環(huán)境會(huì)使我們的精神保持高度集中,能夠激發(fā)出我們的思維,從而在有限的時(shí)間內(nèi)進(jìn)行更多的思考,也能幫助我們適應(yīng)面試的節(jié)奏。多多參加還有機(jī)會(huì)獲得他們官方提供的獎(jiǎng)勵(lì)!雖然我這小菜雞一次也沒拿到 555。
此外,參加藍(lán)橋杯競賽也是不錯(cuò)的,我自己也參加了兩屆,題目的難度和找工作要求的算法題目難度相當(dāng),也能發(fā)現(xiàn)自身的不足、激勵(lì)自己進(jìn)步吧。
5. 考取證書
這幾年,PAT 計(jì)算機(jī)程序設(shè)計(jì)能力考試在逐漸升溫,分為頂級、甲級、乙級三個(gè)級別。

我親身參與過甲級和乙級的考試,難度適中,雖然目前這個(gè)證書的含金量不高,但在備戰(zhàn)考證的過程中,你有一個(gè)學(xué)習(xí)的目標(biāo),會(huì)更有動(dòng)力堅(jiān)持下去。在我看來,過程大于結(jié)果。
網(wǎng)址:https://www.patest.cn/
6. 看文章
其實(shí)很多零碎的時(shí)間,大家也可以利用起來,看一些推送、文章之類的,比如我大二暑假坐高鐵實(shí)習(xí)的路上就是看小灰的漫畫來學(xué)算法,5 - 10 分鐘一篇,這個(gè)時(shí)間不保證你能學(xué)會(huì),但看了之后最少能讓你對算法有個(gè)基礎(chǔ)的印象。時(shí)間就像我腦袋里的水,擠一擠還是有的,想超過那些比你有天賦的人,就一定要利用好時(shí)間。
算法競賽刷題
再聊聊目標(biāo)成為算法競賽大神的同學(xué)應(yīng)該怎么刷題吧,不過這個(gè)話題,我確實(shí)不夠?qū)I(yè)。
老實(shí)講,我只在大一大二的時(shí)候參與過幾場 ACM 算法競賽,雖然沒有拿到很好的成績,但還是可以很負(fù)責(zé)任的告訴大家,算法競賽的難度和需要的訓(xùn)練強(qiáng)度可不是一般的同學(xué)能承受的!想要拿到不錯(cuò)的競賽成績,至少要在以下任意一個(gè) OJ 平臺(tái)刷個(gè)幾百題,而且確實(shí)也需要一定天賦(數(shù)學(xué)、邏輯、英語等),不然會(huì)更累。
直接在編程導(dǎo)航搜索 OJ 可以直接看到所有的 OJ 平臺(tái),比如北京大學(xué) POJ、浙江大學(xué) ZOJ 等,都非常不錯(cuò)!
地址:https://www.code-nav.cn/resources/algorithm?q=oj

至于什么時(shí)候可以停止刷題了呢?這也要看你刷題的目的,是找工作還是持續(xù)鍛煉思維提升自己?
我身邊一些同事還保留著刷算法的習(xí)慣,但我找到工作后,對算法的態(tài)度就像是仇人了,不想見,能不見就不見。
無論如何,刷題一定要拉長戰(zhàn)線、養(yǎng)成習(xí)慣,每天最好固定一個(gè)時(shí)間,堅(jiān)持做幾道題目,比如我當(dāng)時(shí)是每天早上還在床上躺著時(shí),掏出手機(jī)看一道題目,然后閉著眼睛思考一會(huì),想到解法后再起床敲。
千萬不要急于求成、爆發(fā)式刷題!而且除非你對算法很有自信,否則我建議找到工作前不要停止刷題。
最后,萬事開頭難,希望大家不要懷疑自己的能力,更不要懷疑自己的智商。算法和編程語言學(xué)習(xí)一樣,找對方法,付出努力,一定會(huì)有進(jìn)步的!
