题目要求
给定一个字符串,求不含有重复字符的最长子串的长度
解题思路
题目需要找最长的无重复子串,既然是连续子串,那么可以考虑子串的结尾位置,用来代表一段子串。为了达到不重复,我们可以用字典来做到去重的效果。具体做法如下:
-
定义 l o n g e s t longest longest, e n d end end 分别记录最长子串的结果和上一次出现重复字符的最后一个位置
-
如果新的字符在字典中,那么 e n d end end 需要更新为 max e n d , d i c [ c ] \max{}{end, dic[c]} maxend,dic[c]。这是由于如果 d i c [ c ] < e n d dic[c] < end dic[c]<end 那就没必要更新。比如字符串 p w w p pwwp pwwp,在第二个 p p p 处, e n d = 1 end = 1 end=1,而 d i c [ p ] = 0 dic[p] = 0 dic[p]=0, 如果 e n d end end 更新为 0 0 0,就会代表出现重复的 w w w,因此 e n d end end 取最大值更新。
-
每次更新完 e n d end end 和 l o n g e s t longest longest 值以后,再把当前字符的结尾位置更新到字典中
代码
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
n = len(s)
longest = 0
end = -1
dic = {}
for i, c in enumerate(s):
if c in dic:
end = max(end, dic[c])
longest = max(longest, i - end)
dic[c] = i
return longest
复杂度分析
时间复杂度
O
(
n
)
O(n)
O(n) 其中
n
n
n 是字符串的长度,一次遍历就可以得到结果
空间复杂度
O
(
∣
Σ
∣
)
O(\left|\Sigma\right|)
O(∣Σ∣) 其中
∣
Σ
∣
\left|\Sigma\right|
∣Σ∣是字符集的长度,字典中最多需要存下整个字符集