Bootstrap

3298.统计重新排列后包含另一个字符串的字符串数目 I II滑动窗口 优化思路解析全网最详细

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
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

        
;