在LeetCode上刷一道題,題目以下:python
3. 無重複字符的最長子串c#
給定一個字符串,請你找出其中不含有重複字符的?最長子串?的長度。編輯器
示例?1:函數
輸入: "abcabcbb"
輸出: 3
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3。spa
示例 2:調試
輸入: "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。code
示例 3:blog
輸入: "pwwkew"
輸出: 3
解釋: 由於無重複字符的最長子串是?"wke",因此其長度爲 3。
? 字符串
請注意,你的答案必須是 子串 的長度,"pwke"?是一個子序列,不是子串。class
我想到,若是忽略重複的狀況,純對無符號字符串進行分詞,是怎麼作的?
考慮了一下,思路比較簡單:
先從單個字符開始,統計詞頻,而後對詞頻大於1的進行擴展,擴展處理的詞長爲2的,再統計詞頻,而後如此類推,一致推到全部的最高長度詞都詞頻爲1了,才結束。
如圖所示:
最終代碼以下:
#該函數爲,i爲擴充出的詞的長度,i=2,就是ab,bc,de這種兩個長度的詞; #而後在sc中找值不爲1的鍵值對,檢查長度爲i的鍵在s中出現後續詞的數量,並插入到sc字典中 #返回此層結果的最大詞頻 def fillSc(sc:dict,s:list,i:int)->int: maxlens=0 #最大詞頻 if len(sc)==0: #若是sc字典爲空,則開始把單字進行填充 for b in s: sc[b]= s.count(b) if s.count(b)>maxlens: #判斷該詞頻率,若是頻率是最高的,就保存下來 maxlens=s.count(b) else: #不然在sc字典中找到詞長爲i的詞,進行探索 for x in list(sc.keys()): if len(x)!=i: #若是爲詞長與預設不符,則再也不繼續,而是跳過 continue else: m=int(sc[x]) #m爲詞x出現的次數 if m>1:#詞頻爲1的,再也不處理,只處理詞頻高於1的 n=0 #取詞的位置 for k in range(0,m,1): if s.index(x,n,)+len(x)<len(s)-1: #判斷是否到了s字符串的結尾 x1=x+s[s.index(x,n,)+len(x)] #造成後續詞,即x爲ab時,取abc,若是存在多個ab,則接連取 n=s.index(x,n,)+len(x)#後續詞出現的位置 sc[x1]=s.count(x1)#補充進sc列表 if s.count(x1)>maxlens: #判斷該詞頻率,若是頻率是最高的,就保存下來 maxlens=s.count(x1) return maxlens s="abcabcbb" #原始字符串 sc={} #空字典,用於存儲分出來的詞和詞頻 i=0 #當前層數,也就是當前詞的長度,例如a是1,ab是2,abc是3 maxl=2 #最大詞頻數,初始值設置爲2,是爲了不while循環不啓動 while maxl>1: maxl=fillSc(sc,s,i) i=i+1 for x in list(sc.keys()): #將sc字典中的所有輸出 print(x,",",sc[x])
輸出結果以下:
a , 2 b , 4 c , 2 ab , 2 bc , 2 ca , 1 cb , 1 abc , 2 bca , 1 bcb , 1 abca , 1 abcb , 1
心得體會以下:
一、對python的語法和方法仍是不熟悉,致使了很是大的麻煩,通過這個例子,對字典的理解更深刻了,雖然感受不如c#的對應類型好用。
二、代碼編輯器很麻煩,開始用vscode怎麼也配置不上,重裝了後,沒有自動代碼提示,也沒有代碼顏色高亮等,等再配置完了,這些有了,但代碼執行不起來了,提示有空行在覈心代碼庫裏面。最後只能重裝了anaconda3,直接用spyder來寫,調試和代碼執行也很麻煩。若是用vs和c#來寫,估計連四分之一的時間都用不了。