一 读懂题目
二. 分析,推导解法,产生思路。
解题思路1:注意重复字符的位置对子串计算的影响
解题思路2:滑动窗口,维护目标区间
解题思路3:双指针
注意:哈希集合(set),记录每个字符是否出现过
三 代码实现
def lengthOfLongestSubstring_b(self, s):
'''
解题思路:查找子串的过程中,若未遇到之前出现过的字符,则计算子串长度(即当前点与最近未重复的字符(start;子串计数起始位置)之差)
如果遇到前面出现过的字符,则修改子串计数起始位置,重复字符覆盖前一个字符。
eg:'abcabcbb'
初始时,最近未重复位置start无,此处设置为-1;
遇到第一个重复的a后,最近未重复位置为a(即s[0]);后面的子串计算,从s[0]=a以后开始(修改子串计数起始位置),避免了重复元素a;
遇到第二个重复字符b后,最近未重复位置为b(即s[1]);后面的子串计算,从s[1]=b以后开始,避免了新重复元素b;
'''
start = -1
max_len =0
d ={}
for i in range(len(s)):
# 如果出现重复字符x
if s[i] in d and d[s[i]] > start: # d[s[i]] > start:避免出现子串计数起始位置跳回前面已覆盖的重复元素
# 为避免x重复出现,修改子串计数起始位置
start = d[s[i]]
# 不再考虑前一个重复字符,覆盖前一个重复字符
d[s[i]] = i
else:
d[s[i]] = i
# 计算并比较子串长度
if i - start > max_len:
max_len = i - start
print(i,start,d,max_len)
return max_len
def lengthOfLongestSubstring_t(self, s): # 滑动窗口 ''' 维护一个区间,从左至右遍历, 遇到重复字符,计算子串长度并从左至右删除字符直到删除重复字符 ''' if len(s) < 2 : return len(s) set_str = set() max_len = 0 cur_len = 0 left = 0 #删除字符引入的变量 for i in range(len(s)): print(i, max_len, cur_len, set_str) # 遇到重复字符 if s[i] in set_str : # 比较当前子串与最长子串 if cur_len > max_len : max_len = cur_len # 删除字符,直到删除重复字符 while s[i] in set_str: set_str.remove(s[left]) left += 1 cur_len -= 1 set_str.add(s[i]) cur_len += 1 # 处理最后一个子串 if cur_len > max_len: max_len = cur_len return max_len
def lengthOfLongestSubstring_t1(self, s):
# 双指针
left = 0
chars = set()
max_len = 0
for right in range(len(s)):
# 字符不存在于集合,右指针右移一位,添加字符
if s[right] not in chars:
chars.add(s[right])
else:
# 字符存在于集合,左指针右移,直到删除重复字符
while s[right] in chars:
chars.remove(s[left])
left += 1
chars.add(s[right])
# 判断当前子串是否为最长子串
if max_len < right - left+1:
max_len = right - left+1
return max_len