LeetCode 30.串联所有单词的子串

通过滑动窗口解决LeetCode 30题,找到字符串s中所有由words单词完全匹配的子串起始位置。考虑单词重复和重叠,使用队列优化时间复杂度,从不同起始位置开始扫描以覆盖所有情况。
摘要由CSDN通过智能技术生成
LeetCode 30. 串联所有单词的子串

题目描述:

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

注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

思路一:

比较直接的想法应该就是采用滑动窗口的方法。因为单词的长度都一样,因此可以设置一个长度为 “单词个数 * 单词长度” 的滑动窗口,在给定的字符串 s 上进行滑动,因为单词的长度一样,因此可以对窗口内的子串进行等位划分出多个单词,判断每个划分出来的单词是否在单词表里,如果单词在的个数和单词表的个数一致,则记录窗口左端的起始位置,否则窗口向后移动一位

这里要需要考虑单词重复或者单词首尾重叠的问题,因此可以弄一个单词表的暂存数组,在检索单词是否存在时,若存在则将该单词从占存数组中删去,若不存在则 break 后移滑动窗口 (加了 break 才勉强过)

勉勉强强过了,压着时间线过的

class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        index = []
        words_len = len(words)
        if words_len == 0:
            return index
        
        word_len = len(words[0])
        winsize = word_len * words_len
        start = 0
        while start + winsize <= len(s):
            has = 0
            tmp_words = words.copy() # 暂存数组
            substr = s[start : start + winsize]
            for i in range(words_len):
                sub_word = substr[i * word_len : ( i + 1 ) * word_len]
                if sub_word in tmp_words:
                    has += 1
                    del tmp_words[tmp_words.index(sub_word)] # 如果直接remove,相同的单词会全删掉
                else:
                    break
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值