1. 双指针滑窗
相对于暴力法,需要优化搜索空间,滑窗的目的是候选子串的长度至少不少于最长子串的长度,再通过当前子串提供的信息,进行优化
- 常规
思路很简单,使用beg, end两个指针记录当前位置,用is_unique 判定是否为重复子串,如果不是且长度增加则更新end+1,如果是,则滑动窗口+1
def is_unique(counts, s):
counts = dict()
for k, v in enumerate(s):
if v in counts:
return False
else:
counts[v] = True
return True, 1
def lengthOfLongestSubString(s):
if s is None:
return 0
if len(s)<2:
return len(s)
counts = dict()
beg = dict()
end = 1
max_sub = ''
search = 0
while end <= len(s):
sub = s[beg:end]
unique = is_unique(counts, sub, search)
if unique and len(sub) > len(max_sub):
max_sub = sub
end += 1
if not unique:
beg += 1
end += 1
return len(max_sub)
- 优化counts
上面的代码已经包括定义一个全局counts, 每次判重前,可以复用之前的counts,如果重复了,则初始化counts
改动点如下
if not unique:
counts = dict()
def is_unique(dict,s):
# counts = dict()
- 优化步长
上述出现重复字符串时, 都是让滑窗+1,如果counts记录的是第一次出现字符的位置,则可以让滑窗直接跳过重复的字符
改动点如下
while end <= len(s):
sub = s[beg:end]
unique, step = is_unqiue(counts, sub)
if unique and len(sub) >= len(max_sub):
max_sub = sub
end += step
if not unique:
beg += step
end += step
counts = dict()
def is_unique(counts, s):
for k, v in enumerate(s):
if v in counts:
return False, counts[v]+1
else:
counts[v] = k
return True, 1
- 优化查重起点
上次查重的字符串是str,如果未出现重复,则这次会查询str+1,则没有必要对[str] 的部分再查询一次
改动点如下
if unique and len(sub) >= len(max_sub):
max_sub = sub
end += step
search = len(sub)
if not unique:
beg += step
end += step
counts = dict()
search = 0
def is_unique(counts, s, search):
for k,v in enumerate(s):
if k<search:
continue
if v in counts:
return False, counts[v] + 1
else:
counts[v] = k
return True, 1
来源:oschina
链接:https://my.oschina.net/u/4215839/blog/3216312