为了在O(n)的时间复杂度内完成。需要一次遍历就得到结果
所以,我们在一次遍历的过程中检查当前不重复子串的长度,并更新最长子串的长度
为了记录当前遍历到的字符cur是否出现在不重复子串中,我们使用字典dic记录cur前一次上一次出现的位置:
1、如果dic的keys中没有cur则记录当前位置
2、如果有,则更新cur当前位置
使用start记录当前不重复子串的起始位置,初始为0
maxLen记录最长子串的长度,初始为0
过程是这样的:
从头遍历字符串,记录当前位置 i 的字符为cur。
1、如果cur没有包含在不重复子串中,记录cur的位置
dic[cur] = i
2、如果cur已经出现过
1)当前不重复字串中包含上一次出现的cur,即dic[cur] > start
将start移动到 i 之后,防止不重复子串中出现重复字符
2) 当前不重复子串中不包含上一次出现的cur,即dic[cur] < start ,不做任何操作
判断完成后,更新dic[cur] = i
检查当前不重复子串的长度是否大于maxLen,更新maxLen
1 class Solution(object): 2 def lengthOfLongestSubstring(self, s): 3 """ 4 :type s: str 5 :rtype: int 6 """ 7 maxLen = 0 8 start = 0 # 最长子串开始的位置 9 dic = {} # 字典,用来记录某字母是否出现过,以及出现的位置 10 for i in range(len(s)): 11 cur = s[i] 12 if cur not in dic.keys(): # 没出现过 13 dic[cur] = i 14 else: # 出现过 15 # 若当前字符包含在最长子串中,需要将最长子串start移动到dic[cur](上次出现的位置)的后面,使不出现重复字符 16 if start <= dic[cur]: 17 start = dic[cur] + 1 18 dic[cur] = i # 更新cur最新出现的位置dic[cur] 19 # 检查当前len是否大于最大长度 20 if i-start+1 > maxLen: 21 maxLen = i-start+1 22 return maxLen