刷題難,程式設計師如何玩轉力扣?

語言: CN / TW / HK

前言

大家好,我是bigsai,好久不見!今天就給各位小夥伴分享我自己刷題力扣的一些小方法,不一定很有用但是可以參考,祝你更高效的變強!

最近在一些群聊、私聊中遇到很多的一個問題就是:刷題,大家也都重視到演算法刷題對衝擊大廠的重要性,越來越多的人開始捲起來了!

BA321C5AFE6864CE60465A0E7A3DB133

但有的人是這樣捲起來的,卷的自己都懵了。

20404222C6C4C33D6665B8A077A597A1

今天,我就給偏初學者的各種問題談談個人刷力扣這方面的觀點。

刷哪些題?

大家刷力扣,目標肯定就是為了衝擊大廠的面試筆試,小部分就是為了堅持刷題保持感覺提升自己演算法程式設計能力,那麼你肯定要把重點內容先掌握,哪些是重點內容呢?

劍指offer:

首先是劍指offer https://leetcode-cn.com/problem-list/xb9nqhhg/ ,劍指offer的優先順序還是很高的,就業必刷。在牛客上和力扣平臺上都可以刷劍指offer的題,但是我個人更推薦力扣這個平臺,我第一次刷劍指offer就是和大家在牛客平臺上刷的(雖然有點時間不知道還有沒有人記得),但是前一段時間在力扣上刷劍指offer,有部分題(很少)把自己很久前的程式碼提交試了一下發現wa了。所以牛客測試資料相對還是比較弱的,力扣上的測試資料相對較多,在大部分情況,你過了程式碼基本上就沒有什麼邏輯漏洞了。

除了劍指offer名氣大,我推薦你刷劍指offer的一個原因是劍指offer的題目是真的經典!短短六十多道題,內容覆蓋常見資料結構比如連結串列、二叉樹、圖、佇列、棧、雜湊表等等,常見的演算法和經典問題包過二分、動態規劃、全排列問題、滑動視窗、貪心、分治、排序、位運算、dfs、bfs等等,刷完這些題,是真的可以收穫和學到很多!

另外一方面就是劍指offer在面試筆試中出現是真的非常高頻 ,面試官考察的題目一般都是經典題,面試官不創造題目,只抽選題目,而抽選題目的題目基本就是力扣和劍指offer的題目,劍指offer就是非常高頻的題庫之一。

image-20211018160404291

力扣HOT100|力扣前200

力扣HOT100:https://leetcode-cn.com/problem-list/2cktkvj/

力扣前200:https://leetcode-cn.com/problemset/all/

優先力扣HOT100,力扣HOT100是對力扣某一時間(因為力扣題一直在增加)題庫選出的100道優質題,這些題跟劍指offer類似,都是一些高頻問題,有不少問題確實還是有難度的,對於不少人來說特別容易卡殼。但是如果力扣HOT100能刷完,那你其實加上劍指offer快200的題量就挺可觀的了。

力扣目前已經有兩三千道題目,並且還在增加,所以想刷完力扣,幾乎是不太可能的,如果想順序刷,還是推薦前200,力扣前200和力扣HOT100重合很大,前兩百質量還是很高的(不是意思後面質量不高,只是那麼大題庫刷到後面就會出現很多同類型、同套路的題目),所以還是推薦刷完力扣前200的。

刷完這幾個部分大概能夠擁有接近300高質量題的刷題量,我覺得應對大部分的網際網路公司面試是足夠足夠了,出一些變換自己也能夠相對容易的看出來。

刷題順序?

上面列舉了待刷的題庫,既然知道了要刷哪些題,有沒有一個比較推薦的刷題順序呢?是否需要分類刷?

是否要分專題分類我感覺這個看人的。

如果你有資料結構與演算法基礎,比如考研或者平時資料結構學的還不錯,常見資料結構與演算法原理明白能夠實現部分,又或者有部分刷題經驗,那麼我推薦你直接順序著刷就完了。從客觀來說,力扣和劍指offer上面的題目有難題,也有需要高階資料結構的,但更多的是在資料結構或者邏輯基礎上的巧妙思維題型更多,如果你有資料結構與演算法的基礎,你還是比較容易get到考察點的。順序刷的途中遇到某個不會的技巧或者資料結構,學習一下加入自己的"腦庫"中即可。

如果你是真的小白,那你就要為自己手動找到一條可行走的路,那我推薦你可以按照一些專題去各個擊破。因為你是小白如果順序刷這個題不會,學了,在刷下一題,又學了個完全陌生的新東西。沒有基礎短期內學習太多比較陌生的新東西很難吸收,很容易忘,就會陷入怎麼學不會的苦惱中。所以你可以把刷題當成一個臺階,一層一層往上爬,剛開始找easy easy 那種a+b型別的題求過。對於資料結構方面的題,從連結串列開始先學透單鏈表、雙鏈表、迴圈連結串列各種插入刪除實現,然後在題庫中找連結串列相關題進行逐個攻破(連結串列中的也可細分連結串列插入、刪除、反轉、合併、查詢、排序等等),連結串列大專題之後二叉樹大專題、雜湊…… 這樣你短期內學習某一個數據結構或者演算法技巧,多去刷題鞏固吸收效果比較好!在這種情況切勿覺得簡單就草草下一個,你不敲程式碼,可能不會知道自己會出現什麼問題。

三個為什麼

為什麼見到一個題沒思路?

這種情況大概率是因為見少了,刷題也是個緩慢的過程,見得多刷的多些,來的感覺才能更快一些。還有一部分可能因為給自己安排的刷題路線不夠平和。你上來去肝hard難度的沒思路不是很正常。

簡單題很容易懂實現起來很難?

這種情況可能基礎邏輯可能缺乏訓練,對程式語言的集合框架掌握也有所欠缺。有些題可能涉及到集合框架(Map、Set、List、Stack、Queen)各種巢狀、聯立需要你有個清晰的層次感和邏輯。

你刷題,需要熟練使用一門程式語言,熟悉這個程式語言的常見操作api、集合框架、函式,這些是解決問題的工具幫助我們提高效率(不至於每次手寫個佇列、手寫個雜湊表吧)。

這個問題推薦可以先刷幾道簡單的字串處理問題,字串處理問題很多涉及到的集合框架和邏輯控制比較多,如果時間充足推薦PAT乙級的題目刷一些練手鍛鍊邏輯和程式語言掌握。

看了很多題解為啥還是不會刷題?

看了很多題沒刷那跟沒刷區別不太大,印象微弱。從學習角度,刷題和我們學數學的方式有點相似,學會了數學題公式和例題,但還需要大量練習才能真正掌握。

只有自己親身敲了每一行程式碼,每一行程式碼邏輯是什麼,是自己思考出來的而不是看懂別人的思考。從0到1完整實現整個程式,這才能行成一個完整邏輯,然後可能出現各種bug自己除錯看看找出問題。

可以看題解,看了自己要能完全寫出來才行,如果刷了1000+題,你看了題解不刷沒問題,看個思路過了被卡的地方就行。但如果刷了100不到,那你看懂還是老老實實按照別人的邏輯閉卷式的復現一遍。不去實現說有很多問題,記不住,也沒啥奇怪的。

總結一下,如果刷題量不到100感覺狀態不行就簡單粗暴多刷題先,如果刷了兩三百狀態還是很差那麼就要好好找一下其他原因。

拿到一道題的處理流程

拿到一道題,正確的刷和學習方法是怎麼樣的呢?

確定考察點、確定思路

讀到一個題,讀完題意後首先就是要了解這個題到底考察的內容是什麼?當然如果你按照專題來刷,那可能這方面就容易很多。首先可以確定下題型大型別,是圖論的,還是二叉樹,還是字串的,還有最常見陣列給的一堆資料。就要拿著這個型別的題目往這方面常見演算法考察點靠。比如給個數組資料讓你查詢計算,有可能是雙指標,有可能是雜湊,有可能還是位運算,還可能是動態規劃,還可能是要貪心處理。不過大部分題是在各個經典演算法的經典問題上進行一些變化,要知道經典演算法處理的哪些經典問題。

如果能確定考察點,可以想想細節開始實現;如果確定不了考察點,沒思路,先別直接看題解,看看題目標籤的提示。有時你看一個題可能說:這題啥方法啊我只會暴搜,有的確實就是搜尋剪枝……

image-20211018151027583

除了標籤,還要看資料範圍!資料範圍內的資料都是可能出現的,不同資料範圍可能使用方法不同(這點陣列題較多,有些題巧用雜湊、原地置換對資料有要求)。

如果自己看了標籤想想來靈感那最好,如果還是沒有靈感,那點一下題解。可以從標籤標題中看看能不能有靈感,有不少題解會給足夠多的暗示有些人看到就能明白了。

img

如果還是不會那就老老實實點進去看看別人的思路,有的是視訊,有的是圖文,看懂為止,要是還自己看不懂,要麼請假一下別人,要麼放棄吧!

編寫程式碼、測試

編寫程式碼的過程不要有任何參考!編寫程式碼的過程不要有任何參考!重要的話說兩遍,思路可以看,別人的程式碼也可以看,你自己寫程式碼不要參考和ctrl c + ctrl v,工程專案能跑起來就行為了效率都是cv大法,但是面試筆試題基本要你閉卷,有的還要你用線上IDE連提示都不全的。

寫程式碼常常要考慮常見問題:測試資料邊界(比如Integer.MAX_VALUE,Integer.MIN_VALUE這種邊界數值),迴圈控制邊界處理,末尾資料處理(有時候會被遺忘處理),特殊異常情況考慮,數值範圍是否合理,演算法複雜度是否能夠跑出來,資料深淺拷貝,簡化重複遍歷和操作,變數命名清晰,註釋較為完整……

寫完程式碼,用測試案例多測測,確保萬無一失。力扣經常出空值測試案例,因為這個wa了很多次……

如果出現和想象中不一樣的問題,先看一遍自己程式碼邏輯看看能否看出問題,如果看得出正好,看不出的話自己列印輸出或者debug找找問題,直到改對為止,有很多題需要考慮比較全才能ac。

方法、結果對比

不要以為ac了就完了,你要看看自己時間上超越了多少人,推薦從這兩個維度來衡量自己的程式碼:

要超越70%以上的人(根據自己要求適當提高):大部分題超越70%說明你的方法上是沒問題的,可能有些小的方面可以進行優化。比如StringBuilder替代String進行字串拼接,使用char[]陣列替代String進行遍歷列舉等等。

自己的方法在好方法時間範圍內:有些題比較卷,大家都是最快方法你的程式碼可能比別人差1ms就顯得很慢,這時你只要確定你的方法很優秀就可以不一定要追求100%,並且這個時間花銷不同評測姬出來結果可能也不同的。可以看看大家的時間花銷區間,如果你的方法跟最快的在幾ms或者30%時間範圍,其實都是ok的。別人4ms,你5ms沒啥問題,別人50ms,你70ms也沒啥問題,但是如果別人80ms你800ms那差的太多就要看看自己邏輯和程式碼了。

image-20211018155617921

另外,力扣你點選前面時間的柱狀圖是可以看到別人時間開銷較小的程式碼(有的現在跑可能因為測試資料變動沒那麼快了),可以參考學習一下別人的處理方式。

image-20211018160012025

鞏固提高

過了這道題,可以看看題解區別人有沒有更巧妙的處理方法,當你自己ac之後和別人有個直接對比印象會比較深刻:還可以這樣!

如果感覺這類題型掌握不紮實還想再練一下可以看相似題型去及時鞏固一下。

結語

上面的一些方法僅限於給一些初學者建議,不一定很準確高效可以參考,如果上面題差不多有閒餘之力,推薦可以跟著每日一題打卡,半年就是180+題量,一年就是365題量,相當客觀!

首發原創公眾號bigsai,歡迎關注,一起進步!