题目描述:

方法一:暴力O(MN)
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
res = []
if not s or not words:
return res
for j in range(len(s)-len(words[0])*len(words)+1):
i = j
tmp = words.copy()
while i - j <= (len(words)-1)*len(words[0]):
if s[i:i+len(words[0])] in tmp:
tmp.remove(s[i:i+len(words[0])])
if not tmp:
res.append(j)
i += len(words[0])
else:
break
return res
优化:
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
from collections import Counter
if not s or not words:return []
one_word = len(words[0])
all_len = len(words) * one_word
n = len(s)
words = Counter(words)
res = []
for i in range(0, n - all_len + 1):
tmp = s[i:i+all_len]
c_tmp = []
for j in range(0, all_len, one_word):
c_tmp.append(tmp[j:j+one_word])
if Counter(c_tmp) == words:
res.append(i)
return res
方法二:滑动窗口: O(N)
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
from collections import Counter
if not s or not words:return []
one_word = len(words[0])
word_num = len(words)
n = len(s)
if n < one_word:return []
words = Counter(words)
res = []
for i in range(0, one_word):
cur_cnt = 0
left = i
right = i
cur_Counter = Counter()
while right + one_word <= n:
w = s[right:right + one_word]
right += one_word
if w not in words:
left = right
cur_Counter.clear()
cur_cnt = 0
else:
cur_Counter[w] += 1
cur_cnt += 1
while cur_Counter[w] > words[w]:
left_w = s[left:left+one_word]
left += one_word
cur_Counter[left_w] -= 1
cur_cnt -= 1
if cur_cnt == word_num :
res.append(left)
return res