Substring with Concatenation of All Words
寻找包含所有单词的子字符串,按照人工寻找的方式有如下代码,对于每一个index依次进行比对,该方案通过了167/169,最后两个字符串超时了
class Solution(object):
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
ls = len(s)
lw = len(words)
if not ls or not lw:
return -1
wl = len(words[0])
res = []
dic = {}
for word in words:
if not dic.has_key(word):
dic[word] = 1
else :
dic[word] += 1
i = 0
while i + wl <= ls:
if s[i: i+wl] not in words:
i += 1
else :
tdic = {}
tdic[s[i: i+wl]] = 1
j = 1
while i + j * wl + wl <= ls:
if s[i + j * wl: i + j * wl + wl] not in words:
#i = i + 1
break
else :
if not tdic.has_key(s[i + j * wl: i + j * wl + wl]):
tdic [s[i + j * wl: i + j * wl + wl]] = 1
j += 1
else :
if tdic[s[i + j * wl: i + j * wl + wl]] < dic[s[i + j * wl: i + j * wl + wl]]:
tdic [s[i + j * wl: i + j * wl + wl]] += 1
j += 1
else :
break
flag = 0
for key in dic:
if not tdic.has_key(key):
flag = 1
break
elif tdic[key] != dic[key]:
flag = 1
break
if not flag :
res += [i]
i += 1
return res
研究一下讨论区的其他算法:
class Solution(object):
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
if not s or not words or not words[0]:
return []
n = len(s)
k = len(words[0])
t = len(words) * k
req = {}
for w in words:
req[w] = req[w] + 1 if w in req else 1
ans = []
for i in range(min(k, n - t + 1)):
self._findSubstring(i, i, n, k, t, s, req, ans)
return ans
def _findSubstring(self, l, r, n, k, t, s, req, ans):
curr = {}
while r + k <= n:
w = s[r:r + k]
r += k
if w not in req:
l = r
curr.clear()
else:
curr[w] = curr[w] + 1 if w in curr else 1
while curr[w] > req[w]:
curr[s[l:l + k]] -= 1
l += k
if r - l == t:
ans.append(l)
这个算法实现的主要是一个滑动窗口,当word[0],word[1],word[0]出现时,向后滑一个从word[1],word[0]以及往后开始重新记,其中假设word[0]在words中是唯一的,不唯一时就在超出数量时滑动。为了防止每次滑动一个单词长度遗漏答案,特意将开始的word长度字符分别做头。
AC算法看起来正是用来解决此类问题的,AC算法详解