1. 題目
給定一個(gè)字符串,請(qǐng)你找出其中不含有重復(fù)字符的 最長(zhǎng)子串 的長(zhǎng)度腕够。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "abc",所以其長(zhǎng)度為 3维咸。
示例 2:
輸入: "bbbbb"
輸出: 1
解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "b"簇捍,所以其長(zhǎng)度為 1乙帮。
示例 3:
輸入: "pwwkew"
輸出: 3
解釋: 因?yàn)闊o(wú)重復(fù)字符的最長(zhǎng)子串是 "wke"杜漠,所以其長(zhǎng)度為 3。
請(qǐng)注意察净,你的答案必須是 子串 的長(zhǎng)度驾茴,"pwke" 是一個(gè)子序列,不是子串氢卡。
2. 解題思路
2.1 樸素解法锈至,暴力搜索
為了枚舉給定字符串的所有子字符串,我們需要枚舉它們開(kāi)始和結(jié)束的索引译秦。假設(shè)開(kāi)始和結(jié)束的索引分別為 和 峡捡。那么我們有 ,(這里的結(jié)束索引 j 是按慣例排除的)。因此筑悴,使用 從0到n - 1,n?1 以及 j 從 i+1 到 n 這兩個(gè)嵌套的循環(huán)们拙,我們可以枚舉出 s 的所有子字符串。
要檢查一個(gè)字符串是否有重復(fù)字符阁吝,我們可以使用集合砚婆。我們遍歷字符串中的所有字符,并將它們逐個(gè)放入 set 中突勇。在放置一個(gè)字符之前装盯,我們檢查該集合是否已經(jīng)包含它。如果包含甲馋,我們會(huì)返回 false埂奈。循環(huán)結(jié)束后,我們返回 true定躏。
2.2 滑動(dòng)窗口
利用python 的字典账磺,或者java中的Map<Character, Integer> map
存儲(chǔ)每個(gè)字符出現(xiàn)位置的索引。
使用變量end來(lái)記錄上次該字符出現(xiàn)的位置長(zhǎng)度痊远,刪掉從該字符前一次出現(xiàn)绑谣,及其以前的重復(fù)出現(xiàn),也可以理解成不重復(fù)字符串的開(kāi)始位置拗引;
使用變量m來(lái)記錄不重復(fù)字符出現(xiàn)的最大長(zhǎng)度;
each是遍歷字符串的當(dāng)前index
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if len(s) == 0 : return 0
end = 0
dic = {}
m = 0
for each in range(len(s)):
if s[each] in dic :
end = max(end,dic[s[each]]+1)
dic[s[each]] = each
m = max(m,each-end+1)
return m
第二種理解思路:
求無(wú)重復(fù)字符的最長(zhǎng)子串的長(zhǎng)度幌衣,從頭到尾遍歷字符串時(shí)(索引index)矾削,考慮到無(wú)重復(fù)字符壤玫,我們先把字符逐個(gè)放到容器set中,并更新最長(zhǎng)子串的長(zhǎng)度哼凯,如果遇到了重復(fù)字符欲间,即當(dāng)前遍歷的字符在set中,則要從set中刪除重復(fù)字符断部,包括這個(gè)重復(fù)字符前面的所有字符猎贴,也就是從當(dāng)前子串的最左邊(left)開(kāi)始刪除,直到刪除重復(fù)字符
3. 總結(jié)/分類(lèi)
字符串蝴光,滑動(dòng)窗口