Leetcode做题日记:76. 最小覆盖子串(PYTHON)

给定一个字符串 S 和一个字符串 T,请在 S 中找出包含 T 所有字母的最小子串。

示例:

输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

说明:

如果 S 中不存这样的子串,则返回空字符串 ""。
如果 S 中存在这样的子串,我们保证它是唯一的答案。

第一次的代码:
遍历一遍s,找出每一个合适的子串

	t1=[]
        for i in t:
            t1.append(i)
            if i not in s or len(s)<len(t):
                return ''
        used=t1[:]#表示已经使用过的t中的字母
        ans=''
        ans1=[]
        for i in range(len(s)):
            if s[i] in t: #出现可能存在的序列
                j=0
                while used:#当used非空,即一个可能的子序列未满足要求时
                    if i+j==len(s):
                        break
                    ans=ans+s[i+j] #可能的子序列
                    if ans1 and len(ans)>len(ans1[0]): #若可能的子序列比已有的序列长
                        break
                    if s[i+j] in t and s[i+j] in used: #若是t中的字母,used删除
                        used.remove(s[i+j])
                    j=j+1    
                if (not ans1 or (ans1 and len(ans)<=len(ans1[0]))) and not used:
                    if ans1:ans1.pop()
                    ans1.append(ans)
            i=i+1
            ans=''
            used=t1[:]
        if ans1:
            return ans1[0]
        else:
            return ''

果然在最后一个例子超时
第二次的代码:
用weizhi记录s中属于t的字母的坐标,即答案在这几个坐标中,因为最小串必须是以t中的字母开头结尾的,然后用weizhi列表来遍历,若used列表为空,表示t中字母使用过一遍,得到子串,把子串长度和坐标加入到列表,最后找到最短的子串长度及坐标,返回即可

	t1=[]
        for i in t:
            t1.append(i)
            if i not in s or len(s)<len(t):
                return ''
   
        used=t1[:]
        weizhi=[]
        for i in range(len(s)):
            if s[i] in t:
                weizhi.append(i)
        i=0
        weizhicha=[]
        answeizhi=[]
        while i < len(weizhi):
            j=1
            used=t1[:]
            used.remove(s[weizhi[i]])
            while used and i+j<len(weizhi):
                if s[weizhi[i+j]] in used :
                    used.remove(s[weizhi[i+j]])
                j=j+1
                if j==len(weizhi):
                    break
            if not used:
                weizhicha.append(weizhi[i+j-1]-weizhi[i])
                answeizhi.append([weizhi[i],weizhi[i+j-1]])
            i=i+1
        if weizhicha:    
            index=weizhicha.index(min(weizhicha))
            i=answeizhi[index][0]
            j=answeizhi[index][1]
            return s[i:j+1]
        else:
            return ''

内部出错???什么鬼,刷新了两遍,还是超时了。
第三次代码:
首先建立哈希表T,储存了t内所有的字母及其个数。然后使用两个指针l,r,首先先移动r,当[l,r]内的字符串恰好满足要求时,在该字符串内部可能也拥有满足条件的字符子串,接着移动l,找到满足条件的字符字串,然后,开始第二次迭代,移动r…。使用count来计数满足要求的字符串,哈希表T是为了作为count加减的条件。
举例便于理解:s=abcbcd,t=bc,第一轮迭代,先移动r,得到abc,在移动l,得到bc是满足的,再移动l,得到c不满足了,退出移动l,开始下一轮循环移动r

 	if len(s)<len(t):
            return ''
        T={}
        for i in t:
            if i in t:
                if i in T:
                    T[i]+=1
                else:
                    T[i]=1
        l=0
        r=0
        count=0
        ans=''
        minl=len(s)+1 #取初始最小长度为len(s)+1,因为可能s,t同长度
        while r<len(s):
            if s[r] in T:
                T[s[r]]-=1
                if T[s[r]]>=0:#表示是必须字符,若<0,表明该字符多了
                    count+=1
                while count==len(t): #计数符合要求,r移动完毕,同时准备移动l
                    if (r-l+1)<minl: #测量长度是否符合最小
                        ans=s[l:r+1]
                        minl=r-l+1 #更新最小长度
                    if s[l] in T: #因为l向右移动,s[l]都要移出刚才得到的字符串
                        T[s[l]]+=1 
                        if T[s[l]]>0: #若移出的字符使得字符串不满足要求,count-1退出循环
                            count-=1
                    l=l+1 #继续移动l,即继续删除字符,直到不满足为止
            r=r+1
        return ans             

96ms,排名71%

你可能感兴趣的:(leetcode)