思路每次移动一位会导致很多的重复,所以我们每次判断一个单词
要一次判断一个单词,应该有单词长度减一个起点i,可以参考下面连接
https://leetcode.cn/problems/substring-with-concatenation-of-all-words/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-w-6/
之后我们先将第一个窗口统计好,再每次添加一个新的单词也就是左右指针移动单词大小步
更新统计的单词列表,如果全满足说明符合条件,计入答案。
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
res = []
m,n = len(words),len(words[0])
for i in range(n):
if i + m*n > len(s): #判断剩余数量不够就break
break
need = Counter()
for j in range(i,i+m*n,n): #把第一段分段转化为单词存counter
subword = s[j:j+n]
need[subword] += 1
for word in words: #看看缺哪些词,多哪些词
need[word] -= 1
if need[word] == 0: #刚好的时候删除键
del need[word]
for k in range(i,len(s)-m*n+1,n): #遍历后面的分段注意这里每次移动一个word的长度
if k != i:
subword = s[k+(m-1)*n:k+m*n] #新加入的word
need[subword] += 1 #更新counter
if need[subword] == 0: #不多不少删除键
del need[subword]
subword = s[k-n:k] #加了右边的就要减掉左边的
need[subword] -= 1
if need[subword] == 0: #更新counter
del need[subword]
if len(need) == 0: #如果所有单词都满足,这个窗口符合题意
res.append(k)
return res
暴力解法,每次用满足条件大小的窗口截取字符串,然后把截取的字符串再分割成单词的形式计入ssub
看看分割后的单词和单词表里的是否对应,如果对应计入答案。左右指针右移一位。由于这里是左右指针右移一位,所以算是暴力解法。
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
res = []
need = collections.Counter(words)
l = 0
k = len(words)*len(words[0])
for r in range(k,len(s)+1): #注意以下这里的循环次数,到len(s)
sub = s[l:r]
ssub = []
for i in range(0,len(sub),len(words[0])):
ssub.append(sub[i:i+len(words[0])])
if collections.Counter(ssub) == need:
res.append(l)
l += 1
return res