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