Leetcode刷完了第一次,用了一個半月,完全人肉debug,接受率不到20%,第二次該如何刷?
如題,求各位過來人和大神指導!
題主含淚刷完第一次,精神可嘉!我來給點經驗,如何高效地繼續刷下去。
刷leetcode是為了培養良好的演算法題技巧,良好的演算法題技巧是什麼?
0. 正確性正確性,就是Accepted,是最最基礎的。題主「用了一個半月,完全人肉debug,接受率不到20%」的第一次之旅,我想關注的也只有正確性了。那麼除了正確性,題主還要注重什麼?
1. 良好的代碼風格代碼簡潔明了,變數命名規範,模塊之間疏落有致。整體讓人舒服,就叫風格良好。2. 合適的時間空間複雜度很多題目,都不只有唯一解。好的解法,時間空間複雜度通常更低。刷第一次,可能只關注了容易實現的解法,有沒有考慮過can we do better?當然,時間空間複雜度「合適」就好,為了壓縮它們而讓代碼無比複雜,也是沒必要的。3. 對邊界數據和海量數據的關注測試數據無非三種:1) 常規,用來檢查演算法基本正確,2) 邊界,用來檢查是否細心不掉邊界坑,3) 海量,用來檢查代碼的時間空間複雜度有沒有超出限制。題主寫代碼的時候,有沒有總結出2)和3)有哪些常見的case?4. 小技巧諸如能用位運算就不要用乘除法,之類的。小技巧能給你的代碼,增添一點逼格。
那麼問題來了,這些是理論,最佳實踐在哪裡?
對於C++程序員,我會強烈推薦:soulmachine/leetcode · GitHub看看人家寫的代碼,無比精簡,連全局變數都基本不用(facebook面試官該點贊了~)。對比一下自己的代碼,思考不足之處。soulmachine同學的這份題解,大部分代碼堪稱完美,有些背下來都是應該的。對於Java程序員,因為本人刷題主要用C++,所以也不知道有什麼Java題解。不過呢,思路是相通的,上面的題解,參考價值還是很大。第二第三次刷過後,題主應該能做到我的1234要求了。這時候就要:
1. 學會鞏固鞏固的最好方法,就是把題目按照類別,分成小的list。一個list大概七八道題,每天沒事複習兩個list,記住要敲代碼複習,看是沒用的。高端一點,借鑒下艾賓浩斯遺忘曲線,來鞏固list2. 進階演算法題進階,請參考我的這個回答:大公司筆試面試有哪些經典演算法題目? - Zack 的回答上一張我的進度,上半年前刷完的,現在又出了好多新題:
題主加油!你不是一個人在戰鬥!gogogo!我覺得不要太在意通過率。
Leetcode上很多題目並沒有定義special case的返回值,會需要你錯幾次來看這些special case到底應該返回啥。開一個新的session 刷。。。https://leetcode.com/session/
看到競賽題庫相關問題,感到很親切就進來了。偶多年不搞競賽,都不知道現在有了這麼多在線題庫了。
不過剛剛隨便看了一下那個leetcode,感覺題量太少,還不到1000題,而且題目難度偏低,估計懂點動態規劃、剪枝搜索、圖論演算法就能搞定絕大部分題目了……
想當年我們都是刷 uva, icpc, zoj 的,那裡好多題目都是np-hard的,完全靠優化搜索。當年zoj剛上線時偶一個月刷完了zoj的一千道題,90%以上的acceptance,好像是第一個刷完全部題的,那時真是拚命啊。不知道現在每周uva是否還有國際排名賽了,以前是每周一次,全世界的高手獨立或團隊參加,非常刺激。還有個國際排名榜,清華交大的隊伍常年雄踞榜首;也有個人排行榜,當年也是幾個ioi的金牌得主常年排第一。PS:偶刷題的時代是十五六年前了……題主堅持一個半月,刷完了LeetCode已經是很優秀了。畢竟連一遍都堅持不下來的大有人在。但是我想提醒題主的是,我們刷題的目的並不是真的要幹掉這些題目。而是在刷題過程中快速提高代碼和解題能力,所以千萬不要因為通過率而過於苦惱,重在總結與思考。畢竟我們以後不管是在面試還是在工作中,遇到原題的幾率小之又小。
我也是很熱衷於刷題提高自己的程序員一枚,我經常在 leetcode 和 lintcode 上刷題,這裡也分享一下我自己在刷題過程中的一點小經驗,希望能和題主一起進步。
1.按照類別排序,先做面試易考的題
因為我原先其實也是非計算機專業小白,雖然學完了所有的CS課程,但剛開始刷題的時候還是不知道從哪開始下手。後來做了一下《2017校招常考演算法題歸納典型題目匯總》上的題目,發現常考的演算法題也就是那麼幾類,像是數組、鏈表、字元串、棧之類的。於是我按照類別,選擇面試易考的類別進行刷題,針對性更強、對找工作來說更有幫助
2.多總結與思考,不盲目追求速度
無論是LeetCode,還是LintCode上,都有easy難度的題,也有hard難度的。對於easy的題目,確實是可以快速的做過去,就當鞏固知識點了。遇到通不過的題就停下來多思考,甚至可以去翻閱書籍查看相關內容,也不要輕易的直接看答案找解題方法。解題方案再完美,直接查看也無法轉化成自己的知識。
3.有優化意識
上一條我說到不要直接查看答案,那答案是用來幹什麼的呢?我覺得是用來優化的。在學習的過程中,我們應該有意識的考慮演算法的效率問題以及內存消耗問題。在我們自己寫的代碼通過之後,不妨去認真對比一下LEETCODE/LINTCODE 答案解析 的參考答案,並認真做好筆記,爭取再下一道題中將某種不錯的思路運用進去。
一個半月刷完將近三百道題已經很厲害了。。接下來感覺不刷都行了。。
按照題主的表達,可以看出題主的基礎其實並不是十分好,對題目的熟悉度不夠,刷題也缺乏技巧。
我建議題主,可以多刷一些題,去不同的網站刷題,刷完了LeetCode上的題,就去刷LintCode上的題,刷完了LintCode上的題,就去刷HackerRank上的題。
1.關於題主的正確率
題主刷LeetCode/LintCode/HackerRank的時候,一定要做到刷一題、通一題,再寫下一題,不能你自己以為可以了就寫下一題,不然你寫下來會發現AC率還是不到五分之一,沒有任何提高。
2.關於演算法
有時候題目不過,是因為題主的寫法雖然答案正確,可是時間複雜度很高,所以超時而不過,如果題主遇到這種情況,應該思考哪一步會超時,實在不行就查看LEETCODE/LINTCODE 標準答案解析,明白了之後就把這題標記下來,下次再做一遍加深影響。
3.簡練的代碼表達
題主看答案的代碼一般簡潔明了,言簡意賅,而我們自己寫的常常達不到這樣的效果,這是由於我們的思考不夠嚴謹,書寫的習慣不好導致的,可以多看看《Google 官方代碼風格指南(Java/Python/C++等) 》http://www.jiuzhang.com/qa/5375,在解答的過程中嚴格要求自己。
我明白題主的憂慮,第一次刷AC率才五分之一,而且還是自己用了很大的力氣才寫完的,能不憂慮嗎?
我想說,寫完不是任務,是要提高題主自己,既然不是任務,就每次盡自己最大的努力來進步就好了啊,還有既然不是為了刷題而刷題,那就應該認真的對待每一題對付好自己的每一個缺陷啊,好好改進。
唯手熟耳
1. 首先盡量不要有syntax error,限時做題,力求沒有語法錯誤。
2. 你的bug估計大部分都是邊界情況,比如 &< 還是 &<=,n 還是 n+1,或者具體題目的corner case。 寫多了以後很自然就會用最簡潔的方式實現。
加油!
作為一個上午在timeline看到這個問題然後順手去註冊做了幾道題的新人,題倒是感覺難度不大,每次accept都是領先90+%或直接100%,但大多數錯誤全是低級失誤:分號沒打、變數名寫錯,直接拉低接受率,我只想說,這TM也算?!!!!
ps:C的效率好高喲,遙遙領先c++,甩java,c#幾條大街!第一次都含著淚刷完了。第二次就可以坐上來自己動了。
推薦閱讀: