五十三、開始算法刷題磨練
「@Author:Runsen」
從大一寫Python文章,到現(xiàn)在其都有上百篇,現(xiàn)在到了五十三,我覺得這個時候應該去刷題了,其實很多學Python的都不是??频?,都是給培訓機構宣傳牛逼,其實在編程語言中,Python是最簡單,最沒有難度的編程語言。
我在之后的文章都更新數(shù)據(jù)結構和Leetcode,將會使用Python,Java和JavaScript的語言進行解決
其實Leetcode上的一部分題我都基本刷過,那么我就開始吧。
注冊Leetcode賬號
目前Leetcod有國際和中文的兩個版本,下圖就是我的中文版本,刷的不夠,其實我也挺菜的。這個是中文的網(wǎng)址:https://leetcode-cn.com/problemset/all/
下圖就是我的國際版本,其實我主要在國際版混日子,刷了100多題,其實我很菜的。這是它的官網(wǎng),https://leetcode.com。
不同點,非中國區(qū)的人多點,做完了也可以參考下老外是用什么思路做的,挺好的。所以你比要到非中國區(qū),看看老外是怎么干的。
Pycharm裝Leetcode插件
直接打開Pycharm,依次點擊File-Settings-Plugins-Maketplace ,然后在搜索框輸入leetcode,就會顯示我們的leetcode editor插件,點擊Install,跳出的界面點檢accept,之后等待安裝好就行了
我這個是安裝好的了。
如果你用vscode也是一樣,給我裝vscode插件。

因為,我習慣Python用Pycharm,Java用IDEA,前端用vscode。所以這Runsen使用Pycharm。
然后就是登陸我的Leetcode賬號。

然后就是登錄你的賬號。

點擊右下角,選擇刷新或者加載按鈕,就可以獲取到leetcode中題庫了,根據(jù)顏色可以區(qū)分題目的難易程度: 綠色-中等;黃色-簡單; 紅色-困難

更詳細的使用說明參考文檔:https://github.com/shuzijun/leetcode-editor
怎么刷Leetcode
以前菜雞的我做法
以前Runsen的做法:
打開leetcode 啟動Pycharm 開始思考,冷靜分析 打開leetcode官網(wǎng)的評論區(qū)答案,尋找跟我一樣的菜逼 滿意離開評論區(qū)
上面其實都是像之前的我,都是菜雞,其實現(xiàn)在我還是菜雞。
分類歸納/總結
刷Leetcode,必須分類歸納/總結
(1)、數(shù)組和相關題型
對于算法題,還是有很多種題型需要去總結的,如果你懂這個題型,以后遇到類似的題,相信很快就能做出來的。有哪些題型可以總結呢?答是非常多,例如:
(1)、給你一個非負數(shù)的數(shù)組,求最大子數(shù)組和的長度
這算是一個題型,關于這個題型,有很多種變形、拓展,這里建議一起歸納總結,例如:
(2)、剛才給的數(shù)組是非負數(shù)的,現(xiàn)在變一下,給的數(shù)組是可正可負。
還能繼續(xù)拓展嗎?答是可以的,例如:
(3)、給你個矩陣(即二維數(shù)組),求最大子矩陣和的面積
還有嗎?有,例如剛才是求最大和,現(xiàn)在我改成求最大乘積。
我其實是想告訴你,對于前期的學習,我建議分類刷題,總結題型,像我上面舉的這些例子,遇到相似的,就直接可以秒殺了,因為這類題,沒啥邊界或者規(guī)律。
關于題型的,還是很多的,我這里無法一一給你列舉,只能靠你刷題的過程中,進行分類、總結。不過我可以給你推薦一些資料,后面推薦。下面我在說一些題型吧。
三分學七分練
三分學七分練,這是我從極客時間的覃超,前Facebook工程師,傳授的方法。

俗話說:學鋼琴,三分學,七分練。其中練習是最為重要的一個環(huán)節(jié),想學好鋼琴必須得時常練習且多多益善。
所以刷Leetcode的最大的弊端都是:缺乏練習。
目前我的題量不到150,去面試其實是很不穩(wěn)的,畢竟大二大三專注外功比較多。

兩數(shù)相加
那么我們就開始干他,Leetcode中的Hello World就是兩數(shù)相加。
這個題是我2018年遇見了,現(xiàn)在2020年半,兩年多時間。
題目鏈接:https://leetcode-cn.com/problems/two-sum/
#給定一個整數(shù)數(shù)組 nums 和一個目標值 target,請你在該數(shù)組中找出和為目標值的那?兩個?整數(shù),并返回他們的數(shù)組下標。?
#
#?你可以假設每種輸入只會對應一個答案。但是,數(shù)組中同一個元素不能使用兩遍。?
#
#?示例:?
#
#?給定?nums?=?[2,?7,?11,?15],?target?=?9
#
#因為?nums[0]?+?nums[1]?=?2?+?7?=?9
#所以返回?[0,?1]
#?
#?Related?Topics?數(shù)組?哈希表
由于暴力搜索的方法是遍歷所有的兩個數(shù)字的組合,然后算其和,這樣雖然節(jié)省了空間,但是時間復雜度高,一般來說,為了減少時間的復雜度,需要使用空間來換,這里我們想要使用線性的時間復雜度來解決問題,也就是說,只能遍歷一個數(shù)字,而另外一個數(shù)字呢,可以事先將其存儲起來,使用一個Map數(shù)據(jù)結構,來建立數(shù)字和坐標之間的映射關系
其實這一題真的很簡單,無非就是將“昂貴”的時間復雜度轉換成“廉價”的空間復雜度,把雙重遍歷,變成一次遍歷。典型的空間換時間。
這里最佳的方法就是使用字典,對標算法中的Hash表
下面是我去年的代碼,三種Python代碼的解決方法。
「列表解法」
def?twoSum_1(?nums,?target):
????result?=?[]
????for?i?in?range?(len(nums)):
????????onenum?=?nums[i]
????????twonum?=?target?-?onenum
????????if?twonum?in?nums:
????????????j?=?nums.index(twonum)
????????????if?i?!=?j:
????????????????result.append(i)
????????????????result.append(j)
????????????????return?result
「字典解法」
def?twoSum_2(nums,target):
????dict={}
????for?i?in?range(len(nums)):
????????m?=?nums[i]
????????if?target-m?in?dict:
????????????return?[dict[target-m],i]
????????dict[m]?=?i
「字典推導式」
def?twosum_3(nums,target):
????l?=?len(nums)
????dict?=?{nums[i]:i?for?i?in?range(l)}
????print(dict)
????for?j?in?range(l):
????????a?=?nums[j]
????????b?=?target?-?a
????????if?b?in?dict?and?j?!=?dict[b]:
????????????return?[j,dict[b]]
在Java中的HashMap數(shù)據(jù)類型,Map是泛型,限制是Integer數(shù)據(jù)類型。
map.containsKey(complement) 就是Python中的b in dict
class?Solution?{
????public?int[]?twoSum(int[]?nums,?int?target)?{
????????Map?map??=?new?HashMap<>();
????????for(int?i?=?0;i?????????????int?complement?=?target?-?nums[i];
????????????if?(map.containsKey(complement)){
????????????????return?new?int[]{map.get(complement),i};
????????????}
????????????map.put(nums[i],i);
????????}
????????return?null;
????}
}
由于個人準備的前端的技術棧,需要使用JavaScript的代碼。
反正道理一樣,就是接口不一樣而已,這時你再看看Python那臟代碼,就知道Python就是沒有難度,容易看懂。
/**
?*?@param?{number[]}?nums
?*?@param?{number}?target
?*?@return?{number[]}
?*/
var?twoSum?=?function(nums,?target)?{
???const?map?=?{}
???for?(let?i?=?0;?i????????if(map[target?-?nums[i]?]?>=?0){
???????????return?[map[target?-?nums[i]],?i]
???????}
???????map[nums[i]]?=?i;????????????
????}
}
關于學習課程
在之前深入Leetcode,學了下面的課程



因此下面的文章主要是總結回顧之前學到東西,只有不斷地反復學習,才有新的突破
定期總結和檢驗。刷題刷一道丟一道等于沒刷,一定要善于總結才能真正吃透一道題的收益。要對比參考答案和別人的優(yōu)秀解法,看自己失誤在哪里,思路卡在哪里,是用什么方法解決的?
一道題掌握一個點就是勝利。同時還要定期的去檢驗自己,像以前在學校里的周測月考,通過檢驗來查缺補漏。
?本文已收錄 GitHub,傳送門~[1] ,里面更有大廠面試完整考點,歡迎 Star。
?
Reference
傳送門~: https://github.com/MaoliRUNsen/runsenlearnpy100
更多的文章
點擊下面小程序
- END -

