1. 程式人生 > >【LeetCode 中等題】2-無重複字元的最長子串

【LeetCode 中等題】2-無重複字元的最長子串

宣告:

今天是中等題第2道題。給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。以下所有程式碼經過樓主驗證都能在LeetCode上執行成功,程式碼也是借鑑別人的,在文末會附上參考的部落格連結,如果侵犯了博主的相關權益,請聯絡我刪除

(手動比心ღ( ´・ᴗ・` ))

正文

題目:給定一個字串,請你找出其中不含有重複字元的 最長子串 的長度。

示例 1:

輸入: "abcabcbb"
輸出: 3 
解釋: 因為無重複字元的最長子串是"abc",所以其長度為 3。

示例 2:

輸入: "bbbbb"
輸出: 
1 解釋: 因為無重複字元的最長子串是"b",所以其長度為 1。

示例 3:

輸入: "pwwkew"
輸出: 3
解釋: 因為無重複字元的最長子串是 "wke",所以其長度為 3。
請注意,你的答案必須是 子串 的長度,"pwke"是一個子序列,不是子串。

解法1。首先第一想到的是暴力法,就是窮舉所有可能性,並在每一步都選擇是否要更新最大長度,但這種做法時間複雜度高,為O(n^{3}),所以選擇用滑動視窗的方法,基本思路就是固定下i,j逐漸往後走,長度更新為j-i,直到遇到重複的元素,刪掉第i個元素(這個元素就是重複的),然後i+1,j繼續往後走,該方法時間複雜度為O(n^{2})程式碼如下。

執行用時: 136 ms, 在Longest Substring Without Repeating Characters的Python3提交中擊敗了58.50% 的使用者

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        if not s:
            return None
        i,j = 0,0
        len_s = len(s)
        string = set()
        max_len = 0
        while i < len_s and j < len(s):
            if s[j] not in string:
                string.add(s[j])
                j += 1
                max_len = max(max_len,j-i)
            else:
                string.remove(s[i])
                i += 1
        return max_len

 解法2。上一種解法的優化思路,主要區別是儲存最長字串的容器由集合set改為字典dict,並且在j移動過程中不刪除元素,只更新i值,並用j-i+1作為當前的子串長度和上一輪最長長度相比較來更新最長長度,程式碼如下。

執行用時: 144 ms, 在Longest Substring Without Repeating Characters的Python3提交中擊敗了51.59% 的使用者

class Solution:
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        i,j = 0,0
        string = {}
        len_s = len(s)
        max_len = 0
        while i < len_s and j < len_s:
            if s[j] in string:
                i = max(string.get(s[j],0),i)
            max_len = max(max_len, j-i+1)
            string[s[j]] = j+1
            j += 1
        return max_len

結尾

解法1&解法2:官方解法