LeetCode 30 串联所有子串

给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
在这里插入图片描述

在这里插入图片描述
算法思想:滑动窗口,窗口大小固定
以此题为例,大小为WxK=2x3=6的固定窗口每次向后滑移一位,起点start有N=18种可能性,也就是要经历18次滑移。因为这里写了两重循环,故每次滑移K个字母。
以start=0,3,6,9,12为例,直接进入第二重循环。
在这里插入图片描述

class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        if len(words)==0:
            return  []
        N=len(s)
        W=len(words)
        K=len(words[0])
        ans=[]

        def increment(word,number):
            count[word]+=number
            if count[word]==0:
                del count[word]
        
        for start in range(K):
            current = start 
            if current+W*K>N:    
                continue

            count=collections.Counter()
            for word in words:
                count[word]+=1

            for _ in range(W):
                increment(s[current:current+K],-1)
                current+=K

            if len(count)==0:
                ans.append(current-W*K)

            while current+K<=N:
                increment(s[current:current+K],-1)
                increment(s[current-(W*K):current-(W-1)*K],+1)
                current+=K
                if len(count)==0:
                    ans.append(current-W*K)

        return ans

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值