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