Substring with Concatenation of All Words
You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.
For example, given:
S: "barfoothefoobarman"
L: ["foo", "bar"]
You should return the indices: [0,9]
.
(order does not matter).
每次deepcopy,当S太长时比如7000个时会超时,因此加入needcopy判断:只有从中删除过才需要重新copy。时间从1.9s降到0.1s。
class Solution:
# @param S, a string
# @param L, a list of string
# @return a list of integer
def findSubstring(self, S, L):
from copy import deepcopy
if S=="" or L==[]:
return []
l=len(L[0])
sl=len(S)
ans=[]
needcopy=True
for i in range(sl-l):
start=i
if needcopy:
dic=deepcopy(L)
needcopy=False
while dic:
tmp=S[start:start+l]
if tmp in dic:
dic.remove(tmp)
needcopy=True
start+=l
else:
break
if dic==[]:
ans.append(i)
return ans
当S="a'*5000, L=["a" * 5001]时,超时。加上条件
len(L)>len(S) or len(L)*len(L[0])>len(S)
即可通过。
但是S="ab"*5000, L=["ab","ba"]*250时,仍然超时。。本地运行需要2s+
优化还得从S入手。比如abababab...,每次判断的的子串都是abab...,因此可以加入一个字典hasProcessed={},重复的子串就不需要每次判断了。
toProcess=S[start:start+ll]
if toProcess in hasProcessed:
continue
并在没匹配成功时
hasProcessed[toProcess]=True
本机上0.27s即通过。 但是提交的时候:
Memory Limit Exceeded -_-|||...
把字典换为列表,可以节省内存,但是速度大大降低。。
好吧,,再修改一下,把toProcess先hash()一下,再存到字典里,就不会超内存了。
AC代码如下
<pre name="code" class="python">class Solution:
# @param S, a string
# @param L, a list of string
# @return a list of integer
def findSubstring(self, S, L):
from copy import deepcopy
if S=="" or L==[] or len(L)*len(L[0])>len(S):
return []
l=len(L[0])
sl=len(S)
ll=l*len(L)
ans=[]
needcopy=True
hasProcessed={}
for i in range(sl-l<span style="color:#ff0000;">+1</span>):
start=i
toProcess=S[start:start+ll]
if hash(toProcess) in hasProcessed:
continue
# else:<span style="color:#ff0000;"> 注意位置,应该在匹配不成功时才加入字典!</span>
# hasProcessed[hash(toProcess)]=True
if needcopy:
dic=deepcopy(L)
needcopy=False
while dic:
tmp=S[start:start+l]
if tmp in dic:
dic.remove(tmp)
needcopy=True
start+=l
else:
hasProcessed[hash(toProcess)]=True
break
if dic==[]:
ans.append(i)
return ans