最近刷LeetCode比較頻繁,就購買了官方的參考電子書 (CleanCodeHandbook),里面有題目的解析和范例源代碼,可以省去非常多尋找免費經驗分享內容和整理這些資料的時間。驚喜的是,里面的所有源代碼都是用java語言寫的。
接下來的一段時間里,我會將里面的大部分內容翻譯成中文,再加上一些小y自己的解法和擴展內容,以博客的形式發在博客園。我想,這會是一件非常有趣的事情。
以下是翻譯的前言部分,第1、4題以及其解析部分。
前言:
嗨,各位刷LeetCode的小伙伴們。
就像你們看到這本書的書名,這是一本教人如何在面對面試題時寫出簡潔代碼的指導手冊。
你將會學習到如何寫出優雅的代碼,幫助你順利地通過各種各樣的技術面試。這本電子書將會在你上LeetCode刷題時帶來最好的幫助。
本書中,每一道題目都會有一個“Code it now”的鏈接。點擊這個鏈接,將會打開OJ題目的頁面。用戶可以在這個OJ系統上提交自己的代碼,並且即時得到反饋,知道給出的答案正確與否。如果在點擊“Code it now”之后看到“Coming soon”的提示,那就是這個問題將會在不久的將來被添加進來,敬請期待。
每道題都會注明難度和出現頻率。有三種難度等級:簡單(Easy),中等(Medium),困難(Hard)。簡單難度的題目是那些很容易想到思路,而且實現起來也相當直接的問題。大多數面試中會遇到的問題都是這種類型的。
另一方面,困難難度的題目大多數是算法類型的,需要你在動手寫代碼之前有更多的思考。LeetCode上有一些這類型的題目,但並不多。
另外,還有三種出現頻率的等級:低,中等,高。這里的頻率指的是在面試中會遇到此問題或類似問題的頻繁程度,數據來源於用戶調查:“你是否曾經在一次面試中遇到過這道題目?”通過頻率,我們可以大概知道有多大可能會在面試中遇到同樣或類似的題目。
每一道題目都可能會有“你在面試的時候可以這樣問”(Example Questions Candidate Might Ask),舉例說明你在遇到這道時應該問面試官些什么。弄清楚問題的限制條件是非常重要的,而且這是一個很好的縷清思路的過程。
每一個問題都會有數不清的解決思路。每一個解決思路都會有一個時間復雜度和空間復雜度,這是兩個你在選擇哪一個思路時應該考慮的關鍵因素。在真正開始構建解決方案時,你應該首先分析的是跑這個程序要花多長的時間,和要占用多少的內存空間。在技術面試當中,分析時間復雜度和空間復雜度是非常常見的,每一個面試者都應該好好准備。
獨立解決一個問題是最好的學習途徑。如果你被某一個地方卡住了,本書的提示能為你提供一些小TIPS,幫助你打開思路。如果你看完提示之后還是一籌莫展,那就翻到分析部分並且試着在LeetCode OJ上敲出自己實現的代碼。
即便你覺得某一道題很簡單,但是寫出正確而且整潔的代碼並不是像很多人想象的那樣簡單。舉個例子,如果你在某次面試當中為了解一道題寫了超過30行的代碼,那么很可能是不夠簡潔的。本書中給出的大部分參考范例代碼行數都在20行到30行之間。
第一章:數組和字符串
第1題 兩數加和(Tow Sum)
Code it now! https://leetcode.com/problems/two-sum/
難度:簡單 頻率:高
問題描述:
一個整數數組,找出某兩個數加和等於某一個特定的數(target)。
要求函數twoSum返回符合要求的兩數在數組中所處的位置,index1和index2(index1必須小於index2)。請注意,你所編寫的函數返回值應該是下標加1.(本題只需要考慮僅有唯一解的情況)。
解題方法:
O(n2)的時間復雜度,常數空間復雜度-暴力算法(Brute force)
暴力算法思路非常簡單,遍歷數組中每個元素x並且試圖找到是否有另外一個值相加和等於目標數,即target - x。因為每一次匹配值都需要遍歷一次數組剩余元素,所以時間復雜度是n平方。(譯者注:原作並未提供暴力算法的代碼,以下是我的解法)
O(n)的時間復雜度,n的空間復雜度-哈希表(Hash table)
通過將數組的值和索引使用哈希表存儲起來,我們可以把匹配值的時間復雜度降為1。
(譯者注:LeetCode還會在用戶提交答案AC之后提供其解法與其他用戶解法的量化對比數據)
暴力算法的性能——57ms
哈希表的性能——6ms
第四題 回文(Valid Palindrome)
Code it now! https://leetcode.com/problems/valid-palindrome/
難度:容易 頻率:中等
問題描述:
給出一個字符串,判斷其是否一個回文字符串,只考慮字母和數字,而且忽略大小寫。
例如,“A man, a plan, a canal: Panama” 是一個回文字符串,而“race a car”不是一個回文字符串。
面試者可以會問這樣的問題:
問:空字符串算是回文字符串嗎?
答:在這個問題里,我們將空字符串運定義為回文字符串。
解答方法:
O(n)時間復雜度,常數空間復雜度
思路非常簡單,有兩個“指針”——一個為“頭指針”,另一個是“尾指針”。兩“指針”相向移動直到移動,跳過所有非字母或非數字的字符。
如果一個字符串只有非字母和非數字的字符,也是回文字符串,因為空字符串也是回文字符串。
算法性能——9ms
譯者的話:
學了算法到底有沒有用?
以前我覺得沒什么用,工作很長一段時間都沒有用上。后來刷了LeetCode,在老大交給我的幾個任務里都用到了一些,例如這一章譯文中提到的哈希表,直接把某個數據篩選環節的運行時間從原來的半個小時縮短到10秒,速度足足提升了將近兩百倍。
算法並不是沒有用,而是如果一個程序員不懂算法,在實際的編程中他就想不到用哪個算法比較好,只會一味用暴力算法或者是API自帶的函數。我驚喜地發現,如果你開始懂一點算法,知道在什么情景下適用,將會帶來超乎想象的好處。
另一方面,也不要把算法想得那么高深和艱澀,大部分實用的算法都只是20行左右的代碼就能實現。
只要你能鼓起勇氣,克服因為未知而產生的恐懼,花一點時間和耐心去學習,將會看到一個完全不一樣的世界。
(轉發隨意,轉載請注明作者與博客園原地址)
(我的個人微信公眾號:scut_xiaoy,搜索ID或掃描下方二維碼添加關注,關注程序員自身成長和互聯網時代下的新變化)