II相比于I是数据范围变成了10的6次方了
我们来维护大小关系,把不用的都去掉,优化到O(26n)
首先判断一下要找子字符串的s长度是否小于t字符串,如果小于的话直接返回0
初始答案变量和left左指针为0
用Counter来记录t中所有字符出现次数(当然记录s字符串出现次数也是可以的)
然后用变量b遍历s字符串 把Counter (代码中是cnt )对应的字符都减少1
如果有减少到0的cnt[b]。证明less减少1,即不满足的字符减少1
当less为0,即找到一个满足s的子串可以是t的前缀,已知是如果我这个子串是满足的,我可以右移我的left,直至到最小,那么我有多少个满足的?是有0…left-1即left个
下面给出优化前和优化后的代码
优化前:
class Solution:
def validSubstringCount(self, word1: str, word2: str) -> int:
ans=left=0
count_1=Counter()
count_2=Counter(word2)
for right,x in enumerate(word1):
count_1[x]+=1
while count_1>=count_2:
count_1[word1[left]]-=1
left+=1
ans+=left
return ans
主要优化while count_1>=count_2:语句,这里不管26个子母是不是出现,都会比较一遍
优化后我只会比较我出现的
class Solution:
def validSubstringCount(self, s: str, t: str) -> int:
#移入一个s的字符,那么总共的Counter会减少1
#优化到O(26n) 就是把不用比的去掉,维护大小的关系
#这里不断缩小左边left 不断找到所有的合法的子字符串
if len(s)<len(t):
return 0
ans=left=0
cnt=Counter(t)
less=len(cnt)
for b in s :
cnt[b]-=1
if cnt[b]==0:
less-=1
while less==0:
if cnt[s[left]]==0:
less+=1
cnt[s[left]]+=1
left+=1
ans+=left
return ans