簡體   English   中英

具有非重復字符的最長子串

[英]Longest Substring with Non-Repeating Character

我正在嘗試解決在沒有給定字符串重復字符的情況下找到最長子字符串的問題。

class Solution(object):
    def lengthOfLongestSubstring(self, s):
        """
        :type s: str
        :rtype: int
        """
        start = 0
        mlen = -1
        cur_ = {}
        cur = 0

        while(start<len(s) and cur<len(s)):
            if s[cur] in cur_ and cur_[s[cur]] >= start:
                if cur - start > mlen:
                    mlen = cur - start
                start = cur_[s[cur]] + 1    
                cur_[s[cur]] = cur            
            else:
                cur_[s[cur]] = cur
                if cur - start > mlen:
                    mlen = cur - start
            cur = cur + 1            
        return mlen

x = Solution()
print(x.lengthOfLongestSubstring("abababcdef"))

我想我正在正確解決它:

遇到重復的字符時,請開始一個新的子字符串。

但是我沒有得到正確的答案嗎?

在上面的示例中,輸出為5,而正確答案為6。

但是對於這種情況:

打印(x.lengthOfLongestSubstring(“ ababa”))

輸出正確,即2。

不知道為什么我無法通過該案件? 謝謝。

我對您的函數進行了一些更改,以返回唯一字符的最長子字符串,而不僅僅是它的長度。 如果您想要長度-您總是可以從字符串中獲取長度。

def get_longest_substring(input):
    """
    :type input: str
    :rtype: str
    """

    current = []
    all_substrings = []
    for c in input:
        if c in current:
            all_substrings.append(''.join(current))
            cut_off = current.index(c) + 1
            current = current[cut_off:]
        current += c
    all_substrings.append(''.join(current))

    longest = max(all_substrings, key=len)
    return longest

longest = get_longest_substring("abababcdefc")
print(longest, len(longest))

代碼通過每個char構建一個char數組。

如果它在數組中已經找到一個char,則保留該數組的副本,將其開頭剪切到該字符並繼續構建。

最后,它選擇找到的最長子字符串並將其返回。

您在else分支中錯誤地更新了mlen ,忘記添加當前字符。 另外,遇到重復時,您不需要更新mlen

if s[cur] in cur_ and cur_[s[cur]] >= start:
    start = cur_[s[cur]] + 1    
else:
    mlen = max(mlen, cur - start + 1)

cur_[s[cur]] = cur
cur = cur + 1             

我可以建議你這個簡單的算法:

1.將所有變量設置為空。

2.對於字符串中的每個字母ch:

2.1。 檢查在當前子字符串的字典中是否存在ch

如果是-檢查cur'子字符串是否長於max(maxSubStr初始化為“”)?,是否-將cur'子字符串設置為max。 將當前找到的子字符串的dict設置為ch ,並將當前子字符串的設置為ch

如果不是,則將 ch添加到當前找到的子字符串的字典中。 並用ch連接 cur'子字符串。

3.返回當前子串最長的長度和最大的長度。

class Solution(object):

def lengthOfLongestSubstring(self, s):
    """
    :type s: str
    :rtype: int
    """

    curSubStr = ""
    curSubStrDict = {}
    maxSubStr = ""
    for ch in s :
        if ch in curSubStrDict :
            if len(maxSubStr) < len(curSubStr):
                maxSubStr = curSubStr
            curSubStrDict = {}
            curSubStrDict[ch] = ch
            curSubStr = ""+ch

        else :
            curSubStrDict[ch] = ch
            curSubStr += ch

    return len(curSubStr) if len(curSubStr) > len(maxSubStr) else len(maxSubStr)

x = Solution()
print(x.lengthOfLongestSubstring("abcaabccdefgfgh")) # 5 = |cdefg|
print(x.lengthOfLongestSubstring("abababcdef")) # 6 = |abcdef|

就像在數組中查找max元素一樣,我們“遍歷”(實際上不是迭代)-substring,而無需重復char-並保存最長的時間。

當我們檢測到當前子字符串中包含的char時,就會發生迭代。 而不是我們迭代到下一個子字符串。

盡管您可以通過在每次迭代中增加標記來跟蹤字符串中的位置,但使用嵌套的for循環會更簡單:

s = "abababcdef"
long_run = max({s[i:b] for i in range(len(s)) for b in range(len(s)) if len(set(s[i:b])) == len(s[i:b])}, key=len)

使用set comprehension ,代碼首先使用嵌套的for循環查找所有可能的子字符串。 每個for循環都會生成字符串長度范圍內的所有值,從而消除了更改上限和下限的需要。 理解會過濾所有包含至少一個重復值的子字符串。 為此,代碼使用set函數刪除所有重復項,從而可以檢查子字符串等級與集合的長度和原始子字符串的長度是否相等。 最后,將max函數應用於集合,以通過鍵len在集合中找到最長的子字符串。

輸出:

'abcde'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM