Skip to content

Commit 5687678

Browse files
authored
feat: update solution to lc problem: No.0010 (doocs#871)
No.0010.Regular Expression Matching
1 parent 3fd9474 commit 5687678

File tree

3 files changed

+84
-26
lines changed

3 files changed

+84
-26
lines changed

solution/0000-0099/0010.Regular Expression Matching/README.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@
5454

5555
## 解法
5656

57-
动态规划法,`dp[i][j]` 表示 s 的前 i 项和 p 的前 j 项是否匹配。
57+
**方法一:动态规划**
58+
59+
定义 `dp[i][j]` 表示 s 的前 i 项和 p 的前 j 项是否匹配。
5860

5961
现在如果已知了 `dp[i-1][j-1]` 的状态,我们该如何确定 `dp[i][j]` 的状态呢?我们可以分三种情况讨论,其中,前两种情况考虑了所有能匹配的情况,剩下的就是不能匹配的情况了:
6062

@@ -64,6 +66,14 @@
6466
- `p[j-1] == s[i]` or `p[j-1] == '.'``*` 前面的字符可以与 s[i] 匹配,这种情况下,`*` 可能匹配了前面的字符的 0 个,也可能匹配了前面字符的多个,当匹配 0 个时,如 `ab``abb*`,或者 `ab``ab.*` ,这时我们需要去掉 p 中的 `b*``.*` 后进行比较,即 `dp[i][j] = dp[i][j-2]`;当匹配多个时,如 `abbb``ab*`,或者 `abbb``a.*`,我们需要将 s[i] 前面的与 p 重新比较,即 `dp[i][j] = dp[i-1][j]`
6567
3. 其他情况:以上两种情况把能匹配的都考虑全面了,所以其他情况为不匹配,即 `dp[i][j] = False`
6668

69+
设 s 的长度为 m,p 的长度为 n,则时间复杂度为 $O(m \times n)$,空间复杂度为 $O(m \times n)$。
70+
71+
**方法二:递归**
72+
73+
方法一的递归形式实现,相比于方法一,代码更容易理解。
74+
75+
设 s 的长度为 m,p 的长度为 n,则时间复杂度为 $O(m \times n)$,由于是尾递归,故空间复杂度为 $O(1)$。
76+
6777
<!-- tabs:start -->
6878

6979
### **Python3**
@@ -160,6 +170,8 @@ public:
160170
161171
### **Go**
162172
173+
动态规划非递归实现:
174+
163175
```go
164176
func isMatch(s string, p string) bool {
165177
m, n := len(s), len(p)
@@ -193,6 +205,34 @@ func isMatch(s string, p string) bool {
193205
}
194206
```
195207

208+
动态规划递归实现:
209+
210+
```go
211+
func isMatch(s string, p string) bool {
212+
var dp func(x, y int) bool
213+
dp = func(x, y int) bool {
214+
if y == len(p) {
215+
return x == len(s)
216+
}
217+
218+
// 匹配
219+
if x < len(s) && (s[x] == p[y] || p[y] == '.') {
220+
// 下一个为 '*'
221+
if y+1 < len(p) && p[y+1] == '*' {
222+
return dp(x, y+2) || dp(x+1, y)
223+
}
224+
return dp(x+1, y+1)
225+
}
226+
// 不匹配但下一个元素为 '*'
227+
if y+1 < len(p) && p[y+1] == '*' {
228+
return dp(x, y+2)
229+
}
230+
return false
231+
}
232+
return dp(0, 0)
233+
}
234+
```
235+
196236
### **JavaScript**
197237

198238
```js

solution/0000-0099/0010.Regular Expression Matching/README_EN.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,31 @@ func isMatch(s string, p string) bool {
180180
}
181181
```
182182

183+
```go
184+
func isMatch(s string, p string) bool {
185+
var dp func(x, y int) bool
186+
dp = func(x, y int) bool {
187+
if y == len(p) {
188+
return x == len(s)
189+
}
190+
191+
if x < len(s) && (s[x] == p[y] || p[y] == '.') {
192+
// 下一个为 '*'
193+
if y+1 < len(p) && p[y+1] == '*' {
194+
return dp(x, y+2) || dp(x+1, y)
195+
}
196+
return dp(x+1, y+1)
197+
}
198+
199+
if y+1 < len(p) && p[y+1] == '*' {
200+
return dp(x, y+2)
201+
}
202+
return false
203+
}
204+
return dp(0, 0)
205+
}
206+
```
207+
183208
### **JavaScript**
184209

185210
```js
Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,23 @@
11
func isMatch(s string, p string) bool {
2-
m, n := len(s), len(p)
3-
if n == 0 {
4-
return m == 0
5-
}
6-
dp := make([][]bool, m+1)
7-
for i := 0; i < m+1; i++ {
8-
dp[i] = make([]bool, n+1)
9-
}
10-
dp[0][0] = true
11-
for j := 1; j < n+1; j++ {
12-
if p[j-1] == '*' {
13-
dp[0][j] = dp[0][j-2]
2+
var dp func(x, y int) bool
3+
dp = func(x, y int) bool {
4+
if y == len(p) {
5+
return x == len(s)
146
}
15-
}
16-
for i := 1; i < m+1; i++ {
17-
for j := 1; j < n+1; j++ {
18-
if s[i-1] == p[j-1] || p[j-1] == '.' {
19-
dp[i][j] = dp[i-1][j-1]
20-
} else if p[j-1] == '*' {
21-
if s[i-1] == p[j-2] || p[j-2] == '.' {
22-
dp[i][j] = dp[i][j-2] || dp[i-1][j]
23-
} else {
24-
dp[i][j] = dp[i][j-2]
25-
}
7+
8+
// 匹配
9+
if x < len(s) && (s[x] == p[y] || p[y] == '.') {
10+
// 下一个为 '*'
11+
if y+1 < len(p) && p[y+1] == '*' {
12+
return dp(x, y+2) || dp(x+1, y)
2613
}
14+
return dp(x+1, y+1)
15+
}
16+
// 不匹配但下一个元素为 '*'
17+
if y+1 < len(p) && p[y+1] == '*' {
18+
return dp(x, y+2)
2719
}
20+
return false
2821
}
29-
return dp[m][n]
30-
}
22+
return dp(0, 0)
23+
}

0 commit comments

Comments
 (0)