Skip to content

Commit f1605ec

Browse files
authored
Create find-all-good-strings.py
1 parent b160862 commit f1605ec

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

Python/find-all-good-strings.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Time: O(m * n)
2+
# Space: O(m)
3+
4+
class Solution(object):
5+
def findGoodStrings(self, n, s1, s2, evil):
6+
"""
7+
:type n: int
8+
:type s1: str
9+
:type s2: str
10+
:type evil: str
11+
:rtype: int
12+
"""
13+
MOD = 10**9+7
14+
def getPrefix(pattern):
15+
prefix = [-1]*len(pattern)
16+
j = -1
17+
for i in xrange(1, len(pattern)):
18+
while j != -1 and pattern[j+1] != pattern[i]:
19+
j = prefix[j]
20+
if pattern[j+1] == pattern[i]:
21+
j += 1
22+
prefix[i] = j
23+
return prefix
24+
25+
prefix = getPrefix(evil)
26+
dp = [[[[0]*len(evil) for _ in xrange(2)] for _ in xrange(2)] for _ in xrange(2)]
27+
dp[0][0][0][0] = 1
28+
for i in xrange(n):
29+
dp[(i+1)%2] = [[[0]*len(evil) for _ in xrange(2)] for _ in xrange(2)]
30+
for j in xrange(2):
31+
for k in xrange(2):
32+
min_c = 'a' if j else s1[i]
33+
max_c = 'z' if k else s2[i]
34+
for l in xrange(len(evil)):
35+
if not dp[i%2][j][k][l]:
36+
continue
37+
for c in xrange(ord(min_c)-ord('a'), ord(max_c)-ord('a')+1):
38+
c = chr(c+ord('a'))
39+
m = l-1
40+
while m != -1 and evil[m+1] != c:
41+
m = prefix[m]
42+
if evil[m+1] == c:
43+
m += 1
44+
if m+1 == len(evil):
45+
continue
46+
dp[(i+1)%2][j or (s1[i] != c)][k or (s2[i] != c)][m+1] = \
47+
(dp[(i+1)%2][j or (s1[i] != c)][k or (s2[i] != c)][m+1] + dp[i%2][j][k][l]) % MOD
48+
result = 0
49+
for j in xrange(2):
50+
for k in xrange(2):
51+
for l in xrange(len(evil)):
52+
result = (result + dp[n%2][j][k][l]) % MOD
53+
return result

0 commit comments

Comments
 (0)