串联所有单词的子串
题目描述
给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
示例 1:
输入:
s = “barfoothefoobarman”,
words = [“foo”,“bar”]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 “barfoor” 和 “foobar” 。
输出的顺序不重要, [9,0] 也是有效答案。
示例 2:
输入:
s = “wordgoodgoodgoodbestword”,
words = [“word”,“good”,“best”,“word”]
输出:[]
解题方法
方法一:
应该可以递归的方法,但是思考方法与滑窗是一样的。
虽然用了滑窗,但是很暴力,还可以优化。
len(words[0])*len(word)长度的滑窗:
当在滑窗中,从最开始,以len(words[0])为一个单词,判断单词是否在words中, 如果在,则保存此单词到word_temp中, 循环去判断下一个单词, 即指针指向i+len(words[0]), 同理判断是否在words中… 直到滑窗截止。
滑窗截止后, 判断words_temp与words是否完全相同(先判断长度是否相同, 在排序后判断是否相等) (还可以先定义一个words_copy, 单词在words中存在时remove此单词,则在此处只需要判断words_copy是否为空即可),如果相同则返回index, 滑窗前进一步。
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
if not words: return []
if not s: return []
len_w = len(words[0])
res = []
for index in range(len(s)-len_w*len(words)+1):
i = index
words_temp = []
while(i<index+len_w*len(words)):
if s[i:i+len_w] in words:
words_temp.append(s[i:i+len_w])
i += len_w
else:
break
#print(words_temp, index)
if len(words)==len(words_temp) and sorted(words)==sorted(words_temp):
res.append(index)
return res