0
点赞
收藏
分享

微信扫一扫

最长不重复连续子串,O(n)时间复杂度

素锦时年_1b00 2022-03-12 阅读 86
python

 依然是来自leetcode的题目

 两种思路,一种暴力,拿当前字符和左侧的不重复连续子串逐一比较,即判断 a[i] in a[0:i]

def longest(a): #最长不重复连续子串,O(n*n)时间复杂度
    if len(a)<2:
        return len(a)
    l=1
    start=0
    for i in range(1,len(a)):
        if l>len(a)-start:
            break
            #若目前求得的l大于等于a[start]到末尾字符的长度,则当前l即为字符串a中最长不重复连续子串的长度
        for j in range(i):
            if a[i]==a[j]:
                start=j+1
            # 比较a[i]与a[i]左侧的字符是否相同,若相同则start更新为j+1,内层循环结束后得到不重复连续子串a[start:i+1]
        l=max(l,i+1-start)
        
    return l
a='abcede'
longest(a)

    

 第二种使用下标列表,其实是同样的思路,但是下标列表可以记录字符上一次出现的位置,判断判断 a[i] in a[0:i]只需一次比较

def longest(a): #最长不重复连续子串,O(n)时间复杂度
    if len(a)<2:
        return len(a),0,a #字符串长度小于2,最长不重复连续子串长度即为字符串自身长度
    index=[-1]*128 #下标列表,记录每个字符的下标
    l,start=0,0 #长度l初始化为0,start为以a[i]结尾的不重复连续子串的起点下标
    count=0 #记录循环次数
    left,right=0,0 #记录最长不重复连续子串(最左侧的)的首尾下标
    for i in range(len(a)):
        if index[ord(a[i])]==-1:
            if i+1-start>l:
                right=i
                left=start  
                l=i+1-start 
                #若字符a[i]没有出现过且不重复连续子串a[start:i+1]长度大于之前的l,更新left,right和l
        else:
            start=max(start,index[ord(a[i])]+1)
            '''字符a[i]出现过,上一次出现位置为index[ord(a[i])],
            若在start右侧,则start更新为index[ord(a[i])]+1,否则start不变'''
        if l>=len(a)-start:
            break   
            #若目前求得的l大于等于a[start]到末尾字符的长度,则当前l即为所求
        index[ord(a[i])]=i #记录字符a[i]最后一次出现的下标
        count+=1 #记录循环次数

    return l,count,a[left:right+1]
a='abcagbc'
print('字符串为:',a)
print('字符串长度为:%d,最长不重复连续子串长度为:%d,循环次数为:%d,最长不重复连续子串为:%s'
 %(len(a),longest(a)[0],longest(a)[1],longest(a)[2]))

输出:

字符串为: abcagbc 字符串长度为:7,最长不重复连续子串长度为:4,循环次数为:6,最长不重复连续子串为:bcag

举报

相关推荐

最长连续不重复子序列

799. 最长连续不重复子序列

0 条评论