LeetCode 刷題記錄 |003:無重複字符的最長子串

題目

image.png

審題

今天這道題,看起來是否是很簡單?ide

但作爲一道中等難度的題目,它可不會讓你失望。敲起你的鍵盤,試着來解下這道題,你會很難找到一個好的思路。學習

事實上,想這個思路也確實花了我很多的時間,是寫代碼時間的好幾倍。spa

首先,要理解 子串 和 子序列 的區別。3d

子串:必須同時具有,連續性和惟一性。
子序列:只須具有惟一性便可。code

個人版本

先說下個人思路。blog

假設一個字符串的長度是10,那我就先從字符串的[0,1]子串查起,假如子串裏沒有重複字符(經過set()去重查看),就繼續查看子串[0,2],若是仍是沒有重複,就繼續查看[0,3],這時候,咱們發現這個子串裏有重複字符(比方說,子串"abcb"),接下來,咱們就要找出是在重複的那個字符的索引(查出是 b,在索引 處)。那下次咱們查找的子串就不是[0,5]了,而是[2,5],就這樣一直往下,直到遍歷完整個字符串。索引

class Solution:
   def lengthOfLongestSubstring(self, s):
       if len(s) == 1:
           return 1

       reset_start= False
       start = 0
       max_len = 0

       for i in range(len(s)):
           # reset_start就爲True,須要從新設置起點
           if reset_start:
               start = new_start

           # 爲何加1,是由於第一次start會和end同樣是0
           end = i + 1
           sub_str = s[start:end]
           len_sub_str= end - start

           if len(set(sub_str)) != len_sub_str:
               # 找出是在哪一個位置重複
               rep_index = sub_str.index(s[i])
               new_start = rep_index + start + 1
               reset_start= True
               continue

           if len_sub_str > max_len:
               # 記錄下迄今爲止最在長度
               max_len = len_sub_str
           skip = False

       return max_len

運行一下,結果不好。只擊敗了24.73%。今天吃不了雞腿了。不太小明真的是盡力了。只能想到這個思路。
ip

image.png

網上的版本

按照慣例,還得上網去學習別人的優秀代碼。ci

真是驚歎,果真是思路決定出路啊。字符串

這種解法很巧妙。

定義兩個變量longestleftlongest用於存儲最長子字符串的長度,left存儲無重複子串左邊的起始位置。

而後建立一個哈希表,遍歷整個字符串,若是字符串沒有在哈希表中出現,說明沒有遇到過該字符,則此時計算最長無重複子串,當哈希表中的值小於left,說明left位置更新了,須要從新計算最長無重複子串。每次在哈希表中將當前字符串對應的賦值加1。

class Solution(object):
   def lengthOfLongestSubstring(self, s):
       longest = 0; left = 0; tmp = {}

       for index, each in enumerate(s):
           if each not in tmp or tmp[each] < left:
               # 計算當前最長的長度
               longest = max(longest, index - left + 1)
           else:
               left = tmp[each]
           tmp[each] = index + 1

       return longest

運行一下,看看吧,擊敗了92.3%。衆望所歸啊。 佩服佩服。

image.png

總結

其實個人思路,和上面那個優秀代碼的思路是一致的。

我作得很差的一點是,在檢測當前子串是否重複這一點上面,我選了一個效率很是低的作法,就是每次循環都要計算下len(set(str_obj)) 和 len(str_obj),而這種是至關耗時的,並且會隨着字符串長度的增加,耗時也線性增長。

而聰明的人,則是經過維護一個字典,來存放惟一值,和惟一值的最大索引。對執行速度的提高,能夠說是很是顯著的。

相關文章
相關標籤/搜索