日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python leetcode_python实现leetcode中无重复字符的最长字串

發(fā)布時間:2024/10/8 python 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python leetcode_python实现leetcode中无重复字符的最长字串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?無重復字符的最長字串是一道經典的額字符串處理算法的題目,日常編程過程中,處理字符串是很多見的。用Python來實現leetcode這道算法題,這題會涉及到一個概念“滑動窗口”的概念。

一、題目描述

給定一個字符串,請你找出其中不含有重復字符的 最長子串 的長度(Longest substring without repeating characters)。

示例 1:輸入: "abcabcbb"輸出: 3解釋: 因為無重復字符的最長子串是 "abc",所以其長度為 3。

示例 2:

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

示例 3:

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

二、解題思路

先來定義一下“子串”,根據題目描述,“子串”就是字符串中截取某一部分,長度從1到該字符串的長度。比如“abc”的子串集合是:

[‘a’, ‘b’, ‘c’, ‘ab’, ‘bc’, ‘abc’]

用 Python 生成這個集合很容易,你是否想到了?

def subs(s: str): results = [] for begin in range(len(s)): for length in range(len(s)-begin): results.append(s[begin:begin + length + 1]) return resultsz = subs('abcde')print(z)

那么問題來了,任意長度為n的字符串一共有多少個這樣的“子串”呢?答案是:(n+1) * n / 2 。從上面的例子很容易得出這個答案:begin等于0時,長度可以有 n – 0 個,begin等于1時,長度可以有 n – 1個,以此類推,總數就是:

n + (n-1) + … + 1 => (n+1)*n / 2

(1)暴力解法

明白了“子串”的概念和獲取方法,自然而然的就得到了最樸素也是最“暴力”的解法:遍歷字符串得到所有“子串”,然后判斷每個“子串”是否有重復字符,最終就會得到無重復最長子串了。

這個“暴力”算法中,計算所有子串的時間復雜度是 O(n2),而判斷一個子字符串是否有重復字符,又要從頭到尾遍歷一遍該字符串,所有最終的時間復雜度可以達到 O(n3)。

這個解法是不能被接受的,提到它全是因為前面對“子串”的解釋及其數量計算,來練習Python對字符串的操作。

(2)滑動窗口

“滑動窗口”這個概念在計算機算法中非常常見。該算法可以把嵌套的循環(huán)轉化為單循環(huán)從而降低時間復雜度。它在很多不同的領域都有應用:

TCP協議的滑動窗口進行流量控制

NLP(自然語言處理)中的 N-gram

圖像處理中的物體識別

有興趣的同學可以深入了解上面提到的應用領域。

下面我們看看,“滑動窗口”如何進行字符串處理。結合題目中的例子“abcabcbb”這個字符串,我們來看看如何找它的無重復最長子串。

首先,我們定義窗口的兩端:begin和end,分別表示要找的子串的開頭和結尾。

開始的時候,begin和end都指向0的位置即‘a’,然后end不斷后移(窗口變寬),當遇到第二個‘a’時(遇見重復字符)就得到一個子串,其長度就是end和begin位置的差。

如何判斷是否遇到了重復字符‘a’呢?需要一個字典作為輔助數據結構,把end從頭開始遇到的每個字符及其索引位置都放到字典里面,end每次移動到新字符就查一下字典即可。

通過字典,我們遇到第二個‘a’時就可以找到存在字典里面的第一個‘a’的位置。為了繼續(xù)尋找無重復子串,begin就要指向第一個‘a’后面一個的位置即‘b’。然后end繼續(xù)后移到‘b’,有發(fā)現它與前面的‘b’重復,計算子串長度賦值給最大長度(需要比較),同時begin要移動第一個‘b’后面的位置即‘c’。

這樣依次移動end到字符串末尾就可以找到最長的子串,“子串窗口”也就從頭移到了末尾。而只需要end從頭到尾的一次循環(huán)即可。

把這個過程用Python實現如下:

class Solution: def lengthofLongestSubstring(self, s: str) -> int: maxlen = 0 memo = dict() begin, end = 0, 0 n = len(s) while end < n: last = memo.get(s[end]) memo[s[end]] = end if last is not None: maxlen = max(maxlen, end-begin) begin = max(begin, last + 1) end += 1 maxlen = max(maxlen, end-begin) return maxlen

提交后就可以看到結果。“執(zhí)行時間”還只是個參考,再一次提交相同代碼結果不是圖中的擊敗91%,而變成了百分之十幾。

總結

以上是生活随笔為你收集整理的python leetcode_python实现leetcode中无重复字符的最长字串的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。