當前位置: 華文星空 > 知識

大家都是如何刷 LeetCode 的?

2020-05-16知識

2020年4月更新:

跳槽告一段落,開啟新的旅程。終於不用再爆肝刷題了 !之後可能只會做做周賽保持手感,畢竟將來還可能再跳槽還要面試。

TL, DR

  1. 零基礎先去學一點【數據結構】,【演算法設計與分析】的課程。
  2. 按題目類別集中攻克,先easy後hard,同時總結套路和樣版。
  3. 註意時空復雜度,一題多解,一解多題。怎麽在送出之後判斷程式碼的時間復雜度達標呢?這裏有個小tips。
  4. 高頻題可以刷第二遍,第三遍。
  5. 參加周賽要趁早。

原文:

作為留學生為了找工作,16年開始使用Leetcode刷題。四年來刷題過千,經歷過求職和跳槽各種面試,也曾當過面試官面試別人,有一些心得體會可以分享。

刷題進度:

2020年初 刷題進度

刷題前的 背景

  • 大陸本科,美國碩士。兩個階段的專業都是電子工程(EE)。
  • 在學校上過的跟刷題相關的課程:C++程式設計, 數據結構與演算法 演算法設計與分析 ,離散數學。
  • 用過的語言有C++,Java。覺得C++更順手,於是選用了C++刷題。
  • 刷題相關的 網站&資料&工具

  • 首先是Leetcode官網了。我用的是國際版 leetcode.com。
  • 國內版leetcode-cn和國際站內容(題庫,周賽)基本一致。也有不同的地方,比如國內版新增了【劍指Offer】和【Cracking the Coding Interview】的內容,也有獨立舉行比賽等活動,做了很多在地化的事情。
  • 國際版Discuss版面更活躍 ,有不少民間題解寫的詳細易懂,回帖也很及時。
  • 我在 網頁編輯器裏直接碼 ,沒有使用IDE或專業的文字編輯器。
  • 優點: 更貼近白板面試場景 ,不需要搭建測試和執行框架。
  • 缺點:沒有程式碼補全(影響不大,刷的多了以後API都記住了),只能透過打印資訊來偵錯,對肉眼debug能力有鍛煉(不一定是個缺點啦,被逼著總結了一些常用演算法樣版,我現在bug也挺少的,出錯也能很快定位)。
  • 兩個查 STL API和庫函式 的網站
  • cplusplus (更新的略慢,c++17的一些特性查不到),
  • cppreference.com(推薦) 。刷題多了,常用api就記熟了,後來就很少查這兩個網站了。
  • 紙和筆 ✏ ️:想不明白的時候在紙上寫寫畫畫,幫助思考。特別是圖論的題目,拿最簡單的test case畫出來就能幫助思考,效果拔群。
  • 手機 :倒計時功能提示時間,時間到了之後如果沒有思路,或WA,或TLE,就到Discuss討論區取經,我一般只會嘗試 思考10-20分鐘 。20分鐘足夠把解題相關的知識和技巧拿出來列舉一遍了,還想不到方案多半是因為有的知識你不知道。所以快去看答案吧。
  • 我的刷題經歷大概有下面幾個階段:

    第一階段 ,16年夏天,刷題分了三個小階段,順序是 easy >> medium >> hard ,題目範圍是題目編號前300道裏的演算法題,刷完用了兩個月。

  • easy 部份,熟悉了cpp的語法以及STL的用法(經常遇到記不住function名字的情況,我會查閱 Reference - C++ Reference 這個網站)。這部份題目基本能獨立寫出來。
  • medium 部份,重溫了基礎的數據結構和演算法,重點總結了各種常見數據結構和演算法。
  • hard部份, 很多題沒有思路,需要看Discuss。
  • 刷題節奏大概是easy階段每天12道,medium階段一天能做8道,hard階段隨緣2~4道。( 早八點到下午六點 ,中間只有吃飯沒別的活動了,晚上跟著ucb的cs61b學學java)每道題AC後,會檢查執行時間。慢的話就去discuss上學習大神們的解法思路,然後自己寫一遍送出。檢視discuss的情況還包括:自己的程式碼寫的很繁雜,邏輯不清晰,自己又理不順時;題目的tag裏提示有別的解法時;想了半小時以上沒思路的時候。
  • 點評一下 這個刷題順序的缺點是,沒有按類別刷,難以發現同類題目的套路。 因為只有發現共性之後,才能總結出套路和樣版,有了樣版之後才能刷題如砍瓜切菜。可惜我後來按照Tag又刷一遍之後才意識到這個問題。所以 建議優先按題目tag刷題。

    第二階段 ,17年春夏,按題目Tag(bfs, dfs, dp ...)把做過的題(前300題)再做一遍並總結,每個類別寫了點筆記。這一遍 總結了很多常用的演算法樣版和套路 ,基本爛熟於心。對於每個Tag,也是按easy>>medium>>hard的順序過的。這一階段感受到水平顯著提高:

  • 思路和程式碼變得更簡潔:大部份題目程式碼量控制在50行以內。
  • 能夠bug free且快速地寫出常用的程式碼塊(比如union find,dfs/bfs幾個變種, binary search, partition 等等)。熟練掌握的樣版和套路使我能夠bug free的解決medium題目。(對於面FB這類面試題目不難但很重視bug free的公司比較重要)
  • 得益於上面一條,medium型別解題時間縮短。
  • 掌握了各種數據結構的時空復雜度 實作的難易程度 。能夠選用更簡單的數據結構,使得執行時間更快。時間復雜度相同的時候,能夠選用更簡單的數據結構,化繁為簡。能用vector堅決不用unordered_map。
  • 插播一些刷題相關的小tips:

  • 和一些朋友討論刷題策略,我們的共識是 精刷是很有必要的 。300題刷2遍吃透要好過600題只刷一遍。
  • 關於刷題的強度。一天一道題這種節奏很難堅持下來,也很難總結出套路和樣版。 有條件的一定要集中時間刷。
  • 有人可能會疑惑,我的進步是因為見過類似的題,而不是因為分析問題的水平提高了。我的回答是, 見多識廣也是能力,熟練套路不等於生搬硬套 ,能快速辨識出題目套路並解決已經不錯,活用知識甚至發明演算法則需要更深入的理解。
  • 第三階段 ,18年找到了一家小公司做軟體工程師,入職後發現不太滿意,於是打定主意跳槽。18年秋季開始至19年中,每周 參與leetcode contest ,保持手感。

  • 18年秋到19年初,周賽只能過三道題(hard題要麽沒思路要麽TLE)。賽後寫篇筆記,分析一下遇到的問題。這階段應該不能算是刷題了(我理解的刷題是短時間內做很多題)。不過 一年contest做滿的話也有200多道題了
  • 19年初在 洛谷練習場 做了幾個專題,DP,圖論,線段樹。參加了google code jam,Round 2被刷。買了幾本演算法競賽的書,看了些基礎內容。這些支線劇情對leetcode刷題幫助有限, 如果你發現可以用oi或者acm的高級演算法解面試題,那麽多半是你想多了。 當然面試官會對你印象深刻,但他可能並不能聽懂你的高級演算法或數據結構,並要求你解釋到他聽懂為止,這其實暗藏風險。實際上,他只是希望你能用常規的辦法做出來。這裏我想說的是:如果你本來就沒搞過演算法競賽,就不要去學這些,耗費很多時間但收益有限。如果你是競賽大神,你可以先丟擲一個你和面試官都理解的常規解法,時間充裕的話,可以再提出你覺得更牛的解法。以線段樹為例,LeetCode雖然有線段樹的題目,但是一般有更基礎,且復雜度相當的解法。又比如Campus Bike這個題,可以用Hungarian 演算法,也可以用DP,面試中能答出DP就已經穩了。
  • 第四階段, 19年下半年 集中刷題準備跳槽 ,同時投簡歷約面試。

  • 這個階段主要刷公司tag的題目和面經。刷題強度很大,特別是面試前一個月,每天10+道medium/hard題。
  • contest結束就看discuss,跟朋友討論,問題不會留到第二天。大部份情況下能做完4道題,進入global前300。
  • 除了刷leetcode,沒那麽忙的時候學習了【演算法導論】的圖論章節和字串匹配章節。【算導】的圖遍歷講的不錯,圖的遍歷是很多圖演算法的基礎,但是我之前掌握的不好。不過面試很少考察圖論和字串匹配的,看這些只是出於興趣。
  • 刷了這麽多題目,面試也並非一帆風順,畢竟演算法只是面試的一部份。掛了幾家公司後,終於在2020年初收獲offer。
  • 2019年的刷題分布圖

    Q&A

    什麽是Leetcode周賽?

  • leetcode 每周有一次周賽,每兩周有一次雙周賽。都是90分鐘4道題目,一般一道easy,兩道medium,一道hard,每道題根據難度不同設定不同分值。比賽有即時排名,根據分值和時間計算排名,每個錯誤送出會導致5分鐘罰時。
  • 難度落在面試的範圍內,和題庫的難度範圍一致,低於演算法競賽。手速快和bug-free顯得更加重要。
  • 為什麽我建議參加LeetCode周賽?

  • 周賽中的題目都是會進入題庫的,有些周賽題目將來會變為僅會員可見,換言之,參加周賽可以免費做新題。
  • 賽後可以看到所有參賽選手的送出,包括排名第一頁大佬們的題解,利於開闊眼界。
  • 幸運的話,你可以在面試裏遇到剛做過的周賽題(別問我怎麽知道。
  • 完成「最優解「到」最好寫的最優解「的跨越。
  • 如果你沒有演算法競賽經歷,不管你之前題目刷的多熟,總是要參加個十幾場才能找到感覺,所以要趁早。
  • 刷LeetCode就能應付面試了嗎,還需要做什麽?

  • 大部份人刷leetcode的目的是為了在面試(無論是OA還是電面還是onsite)的演算法環節成功。但是實際的面試場景要比網頁上做題復雜的多。透過leetcode訓練可以提高解題的硬實力,但還有一些軟的方面(交流,溝通,開發習慣)leetcode環境無法模擬:
  • 和面試官討論清楚題意,輸入輸出,corner case
  • 把思路完整展現給面試官,實作前把演算法講明白,復雜度分析;
  • 盡量bug-free的實作演算法,盡量的易讀,呈現好的程式碼風格;
  • 展現出好的開發習慣,如設計合理的testcase,並在白板上手工測試
  • follow up 問題的交流討論。
  • 因此,只靠leetcode準備演算法面試是不夠的,找有經驗的人幫你模擬面試能夠讓你發現不足。此外別人的面經和自己的親身經歷也十分重要,特別對於找第一份工作的畢業生來說,多看面經多面試總沒有錯。
  • 面試也不是只有coding,也有behavior question,系統設計甚至專業領域知識等等。系統設計更難準備。
  • 祝大家拿到滿意的Offer!