-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy path154_regular_expression_matching.py
More file actions
59 lines (50 loc) · 1.74 KB
/
154_regular_expression_matching.py
File metadata and controls
59 lines (50 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""
Main Concept:
end by '*' and has no matched
case 1-1: `P[j-2:j]` is `c*` and have no matched in `S`
=> `j-2` in `dp[i][j-2]` means ignored `c` and `*`
end by `*` and is the last matched in `*`
case 1-2: `P[j-2:j]` is `.*` and `.` always matched `S[i-1]`
case 1-3: `P[j-2:j]` is `a*` and `a` == `P[j-2]` == `S[i-1]`
=> `i-1` in `dp[i-1][j]` means to check the `?` below
'...a?a'
\|
'...xa*'
case 2: `P[j-1]` is `.` and `.` always matched `S[i-1]`
case 3: `P[j-1]` is `a` and `a` == `P[j-1]` == `S[i-1]`
=> `-1` in `dp[i-1][j-1]` means previous char
"""
class Solution:
def isMatch(self, s, p):
"""
:type s: str
:type p: str
:rtype: bool
"""
if s == p == '':
return True
m, n = len(s), len(p)
MULTI = '*'
ANY = '.'
"""
`dp[i][j]` means the substr end at `s[i - 1]` was matched by
the substr end at `p[j - 1]`
"""
dp = [[False] * (n + 1) for _ in range(m + 1)]
dp[0][0] = True
# dp[i][0] = False # i = 1 -> m + 1
# dp[0][j] -> ?, need to check
for i in range(m + 1):
for j in range(1, n + 1):
if i > 0 and p[j - 1] == s[i - 1] and dp[i - 1][j - 1]:
dp[i][j] = True
elif i > 0 and p[j - 1] == ANY and dp[i - 1][j - 1]:
dp[i][j] = True
elif j > 1 and p[j - 1] == MULTI:
if dp[i][j - 2]:
dp[i][j] = True
elif i > 0 and p[j - 2] == s[i - 1] and dp[i - 1][j]:
dp[i][j] = True
elif i > 0 and p[j - 2] == ANY and dp[i - 1][j]:
dp[i][j] = True
return dp[m][n]