拿什麼拯救你,個人面試之——從零打卡刷Leetcode(No.003)

寫在前邊:
python

小詹一直以爲本身編程能力不強,想在網上刷題,又怕不能堅持。不知道有木有和小夥伴和小詹同樣想找我的一塊兒刷題呢?歡迎和小詹一塊兒按期刷leetcode,每週一週五更新一題,每一題都吃透,歡迎一題多解,尋找最優解!歡迎小夥伴們把本身的思路在留言區分享出來噢編程

前期回顧:【記錄帖】(No.002)從零打卡刷Leetcode
bash

【歡迎關注我的微信公衆號【小詹學python】】微信

上一期有留一個小bug讓小夥伴們找,不知道多少人本身找到了啊?愛學習的人確定本身去嘗試了,確定發現leetcode上運行結果發現輸出不是預期的[7, 0, 8],而是像下邊這樣:學習

Finished in 36 ms
[7, 0.6999999999999993, 8.07, 1]
複製代碼

一個不合預期的地方是出現了小數,還有一個則是鏈表長度不合預期。其實,這個是除法致使的,這裏的除法保留了小數部分,致使進位標誌carry不是咱們須要的整型0或者1了,因此出現了小數,另外一方面進位的錯誤也致使在最高位的時候再次進了一位,即鏈表中多出了個1。修改方法很簡單,只須要在兩處carry位置進行類型轉換,具體以下。或者注意''/''和「//」的區別,後者所除的結果僅保留商(整型),前者即存在小數。ui

carry = int(p.next.val / 10)  #int()強制轉換爲整型
複製代碼

上期沒找出緣由的小夥伴能夠去改過來試試看噢~spa


No.3 Longest Substring without Repeating Characters 3d

原題:code

Given a string, find the length of the longest substring without repeating characters.cdn

題目大意:給出一個字符串,找到最長的沒有重複字符的子字符串,並返回該子字符串的長度。

例如:

Given "abcabcbb", the answer is "abc", which the length is 3.
Given "bbbbb", the answer is "b", with the length of 1.
Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
複製代碼

多是前邊的題目都大同小異,難度也接近。也有多是人的思惟有慣性,小詹又是利用循環嵌套遍歷全部狀況進行判斷的,這種簡單粗暴能夠實現,可是效率很低。大致思路是:第一層循環從字符串的最左側到最右側第二個,即for i in range(0,len(s)-1),第二層循環則從第一層緊跟着的一個到最後一個字符。即for j in range(i+1,len(s));以後經過找出全部不重複的子字符串,比較長度獲得最大長度的子字符串。代碼以下:(須要注意當字符串長度爲0或1的特殊狀況)

def lengthOfLongestSubstring(self, s):
        """ :type s: str :rtype: int """
        max_len = 0 #用這個值記錄咱們要返回的最長子字符串長度
        #當原字符串長度爲0或1的特殊狀況
        if (len(s) == 1 or len(s) == 0):
            max_len = len(s)
        #開始遍歷每個子字符串,並進行長度比較,獲得最長的那個
        for i in range(0,len(s)-1):
            for j in range(i+1, len(s)):
                if s[j] in s[i:j]:
                    if j-i > max_len:
                        right = j
                        left = i
                        #這裏小詹本想返回對應子字符串的左右索引值,以後發現題目沒有要求
                        max_len = right-left
                    break
                elif j == len(s) - 1:
                    if max_len < j - i + 1:
                        max_len = j - i + 1
        return max_len
複製代碼

結果固然是能夠經過的啦,然而時間效率方面不好不好,如圖:

然而,咱們不能知足於這種最低效率的實現結果。下邊提出一個炒雞牛逼的方法,非原創,小詹花了好久才搞明白其思路,其利用到了字典的方法。什麼是字典?請自行補充知識噢(公衆號有語法綜述)。先放代碼後再解釋:

def lengthOfLongestSubstring(self, s):
        """ :type s: str :rtype: int """
        #建立一個空字典,其存放的形式是「單字符:出現位置的索引」
        indexDict = {}
        #存放記錄最大長度和當前循環下的長度
        maxLength = currMax = 0
        for i in range(len(s)):
            #這裏是關鍵,小詹看了挺久的,小夥伴們比我強,應該比較快
            #這裏是當s[i]沒有在以前出現過,則當前長度currMax自動加一
            #當出現了重複字符,則比較當前找到的子字符串長度和歷史最大長度
            #重點是這裏i - indexDict[s[i]] - 1 的含義;代碼後舉例具體講解
            if s[i] in indexDict and i - indexDict[s[i]] - 1 <= currMax:
                if maxLength < currMax:
                    maxLength = currMax
                currMax = i - indexDict[s[i]] - 1
            currMax = currMax + 1                
            indexDict[s[i]] = i 
        return maxLength if currMax < maxLength else currMax
複製代碼

代碼裏對應位置加入了註釋,理解起來應該好不少了,這裏舉例說明下爲何【i - indexDict[s[i]] - 1】表明了當前找到子字符串的長度。

好比字符串'abcdadd',代碼運行過程當中一直迭代到i=3【對應字符d】時,都不知足s[i] in indexDict ,不執行條件語句,而是currMax依次加一,而且將字符信息以{s[i]:i}的形式存放在字典中。當繼續迭代i=4時,進入條件語句,這裏主要解釋【i - indexDict[s[i]] - 1】,檢測到了重複字符'a',以前該字符出現位置爲i=0處即【indexDict[s[i]] =0】這時候當前檢測到的無重複字符子串爲'abcd',長度爲【4-indexDict[s[i]] -1 = 4】。其餘同此例。


往期推薦(關注微信公衆號【小詹學python】)

Python系列之——在北京當房奴的日子~

爬蟲和反反爬蟲(下篇)




相關文章
相關標籤/搜索