题目 Regular Expression Match
正则表达式匹配问题,’.’表示匹配单个字符,’*‘表示匹配大于等于0个前面的字符。匹配的话需要包含整个输入字符串
之前一直没注意preceding这个词,导致我一直没看懂题目TAT
s是输入字符,p是正则表达式pattern
isMatch(“aa”,”a”)->false 没有包含整个输入字符串
isMatch(“aa”,”aa”)->true
isMatch(“aa”,”a*”)->true
isMatch(“aa”,”.*”)->true
isMatch(“aab”,”c*a*b”)->true 因为c*a*b包含了aab的情况
isMatch(“aab”,”ca*b”)->false 因为c*a*b包含了aab的情况isMatch(“abcd”,”b*”)->false
*假设s=abbba,p=a*bba
当前比较的下标是s为i,p为pi
(1)p[pi+1]不是*
。情况比较简单,只要判断当前s的i和p的j上的字符是否一样(如果有p在j上的字符是’.’,也是相同),如果不同,返回false,否则,递归下一层i+1,j+1;
(2)p[pi+1]是*
。那么此时看从s[i]开始的子串,假设s[i],s[i+1],…s[i+k]都等于p[j]那么意味着这些都有可能是合适的匹配,那么递归对于剩下的(i,j+2),(i+1,j+2),…,(i+k,j+2)都要尝试(j+2是因为跳过当前和下一个*
字符)。
题目30. Substring with Concatenation of All Words
给定单词数组words=[“foo”,”bar”],找到字符串str中包含words的所有单词的任意顺序的子串
最开始的思路是用itertools.permutation把words的所有单词的全排列写出来,但是这样会出现内存溢出。
第二个思路是用wordsnum*wordlen大小的窗口去遍历str,然后截出每个单词看看是否在集合words中,在这里把list转换成了set。但是list中可能会出现重复的单词,所以有麻烦。
第三个思路是先用字典记录每个词出现的个数,然后在对窗口中的每个单词判断是否在集合中,并且计数,一旦超过给定次数则失败,但是这种方法在测试的时候1062ms,但是提交的时候就超时了。
class Solution(object):
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
worddir={}
index=[]
if len(words)==0:
return
for i in range(len(words)):
if worddir.has_key(words[i]):
worddir[words[i]]+=1
else:
worddir[words[i]]=1
wlen=len(words)*len(words[0])
for i in range(len(s)-wlen+1):
k=0
wordset = set(words)
count={}
while len(wordset)>0 and s[i+k:i+k+len(words[0])]in wordset:
tmp = s[i+k:i+k+len(words[0])]
if count.has_key(tmp):
count[tmp]+=1
else:
count[tmp]=1
if count[tmp]==worddir[tmp]:
wordset.remove(tmp)
k+=len(words[0])
if k==wlen:
index.append(i)
i+=1
return index
最后是用到一个滑动窗口来解决的
class Solution(object):
def findSubstring(self, s, words):
"""
:type s: str
:type words: List[str]
:rtype: List[int]
"""
worddir={}
index=[]
initwords=set()
if len(words)==0:
return
for i in range(len(words)):
if worddir.has_key(words[i]):
worddir[words[i]]+=1
else:
worddir[words[i]]=1
initwords.add(words[i])
wlen=len(words)*len(words[0])
for i in range(len(words[0])):
j = i
wordset = initwords.copy()
count={}
start = len(s)
while j < len(s)-len(words[0])+1:
subword = s[j:j+len(words[0])]
#print wordset,subword
if subword in wordset:
if count.has_key(subword):
count[subword]+=1
else:
count[subword]=1
if count[subword]==worddir[subword]:
wordset.remove(subword)
if start>j:
start=j
#print subword,count[subword],worddir[subword],len(wordset)
if len(wordset)==0:
index.append(start)
else:
while start<=j and subword not in wordset:
sword=s[start:start+len(words[0])]
if count.has_key(sword):
wordset.add(sword)
count[sword]-=1
if subword in wordset:
j-=len(words[0])
start+=len(words[0])
j+=len(words[0])
return index