https://leetcode.com/problems/substring-with-concatenation-of-all-words/description/
题意:给一个字符串,还有一个字符数组,数组中的字符串应该等长。判断串中是否存在字符数组的任意组合,求他们的起始位置。
思路:数组中字符串等长(设长度为wl)很关键,利用这个条件,周期性的检测字符串即可。
外层循环:wl次
内层循环:n/wl次
复杂度O(n)
class Solution:
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
res = []
n = len(s)
cnt = len(words)
if n == 0 or cnt == 0:
return res
dic = dict()
for word in words: #将数组中字符串存入字典,并统计频率
if word in dic:
dic[word] += 1
else:
dic[word] = 1
wl = len(words[0])
for i in range(wl):
left, count = i, 0 #left记录窗口起点,count记录匹配次数
tdic = dict() #存储匹配中的字符串频率
#窗口大小为wl,每次向前移动wl
for j in range(i, n - wl + 1, wl):
str = s[j : j+wl]
if str in dic: #检测到words中字符串,写入tdic
if str in tdic:
tdic[str] += 1
else:
tdic[str] = 1
if tdic[str] <= dic[str]:
count += 1
else: #检测到更多的合法word,窗口向前滑动
while tdic[str] > dic[str]:
str1 = s[left : left+wl]
tdic[str1] -= 1
if tdic[str1] < dic[str1]:
count -= 1
left += wl
if count == cnt: #匹配次数符合,记录窗口起点到结果集
res.append(left)
# 窗口前移
tdic[s[left : left+wl]] -= 1
count -= 1
left += wl
else: #若不匹配,信息清空,窗口移动
tdic.clear()
count = 0
left = j + wl
return res