Skip to content

Commit 102e11e

Browse files
committed
Update solutions to Regular Expression Matching and Wildcard Matching
1 parent 35c937c commit 102e11e

File tree

2 files changed

+36
-46
lines changed

2 files changed

+36
-46
lines changed

DP/RegularExpressionMatching.swift

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,29 @@
66

77
class RegularExpressionMatching {
88
func isMatch(_ s: String, _ p: String) -> Bool {
9-
let sChars = Array(s), pChars = Array(p)
10-
var dp = Array(repeating: Array(repeating: false, count: pChars.count + 1), count: sChars.count + 1)
11-
dp[0][0] = true
9+
let s = Array(s), p = Array(p), m = s.count, n = p.count
10+
var dp = Array(repeating: Array(repeating: false, count: n + 1), count: m + 1)
1211

13-
for i in 0...pChars.count {
14-
// jump over "" vs. "x*" case
15-
dp[0][i] = i == 0 || i > 1 && dp[0][i - 2] && pChars[i - 1] == "*"
12+
for j in 0...n {
13+
dp[0][j] = j == 0 || (j > 1 && dp[0][j - 2] && p[j - 1] == "*")
1614
}
1715

18-
for i in 0...sChars.count {
19-
for j in 0...pChars.count {
20-
guard j > 0 else {
21-
continue
22-
}
23-
24-
let pCurrent = pChars[j - 1]
25-
26-
if pCurrent != "*" {
27-
dp[i][j] = i > 0 && dp[i - 1][j - 1] && (pCurrent == "." || pCurrent == sChars[i - 1])
16+
for i in 1...m {
17+
for j in 1...n {
18+
if p[j - 1] != "*" {
19+
if p[j - 1] == s[i - 1] || p[j - 1] == "." {
20+
dp[i][j] = dp[i - 1][j - 1]
21+
} else {
22+
dp[i][j] = false
23+
}
2824
} else {
29-
dp[i][j] = dp[i][j - 2] || i > 0 && j > 1 && (sChars[i - 1] == pChars[j - 2] || pChars[j - 2] == ".") && dp[i - 1][j]
25+
if j > 1 {
26+
dp[i][j] = dp[i][j - 2] || ((p[j - 2] == s[i - 1] || p[j - 2] == ".") && dp[i - 1][j])
27+
}
3028
}
3129
}
3230
}
3331

34-
return dp[sChars.count][pChars.count]
32+
return dp[m][n]
3533
}
3634
}

DP/WildcardMatching.swift

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,31 @@
66

77
class WildcardMatching {
88
func isMatch(_ s: String, _ p: String) -> Bool {
9-
let sChars = Array(s), pChars = Array(p)
10-
var dp = Array(repeating: Array(repeating: false, count: p.count + 1), count: s.count + 1)
11-
dp[0][0] = true
9+
let s = Array(s), p = Array(p), m = s.count, n = p.count
10+
var dp = Array(repeating: Array(repeating: false, count: n + 1), count: m + 1)
1211

13-
// must start from 0, to make range feasible and handle empty vs. * case
14-
for i in 0...s.count {
15-
for j in 0...p.count {
16-
guard j > 0 else {
17-
continue
18-
}
19-
20-
let pCurrent = pChars[j - 1]
21-
22-
if pCurrent != "*" {
23-
dp[i][j] = i > 0 && dp[i - 1][j - 1] && (pCurrent == sChars[i - 1] || pCurrent == "?")
24-
} else {
25-
// Two situations:
26-
// (1) '*' is the first character in p;
27-
// (2) For k>=0 and k<=i, there is some dp[k][j-1] being true;
28-
// and '*' will match the rest sequence in s after index k;
29-
var flag = false
30-
for k in 0...i {
31-
if dp[k][j - 1] {
32-
flag = true
33-
break
34-
}
12+
for j in 0...n {
13+
dp[0][j] = j == 0 || (dp[0][j - 1] && p[j - 1] == "*")
14+
}
15+
16+
if m < 1 || n < 1 {
17+
return dp[m][n]
18+
}
19+
20+
for i in 1...m {
21+
for j in 1...n {
22+
if p[j - 1] != "*" {
23+
if p[j - 1] == s[i - 1] || p[j - 1] == "?" {
24+
dp[i][j] = dp[i - 1][j - 1]
25+
} else {
26+
dp[i][j] = false
3527
}
36-
37-
dp[i][j] = flag || j == 1
28+
} else {
29+
dp[i][j] = dp[i][j - 1] || dp[i - 1][j]
3830
}
3931
}
4032
}
4133

42-
return dp[s.count][p.count]
34+
return dp[m][n]
4335
}
4436
}

0 commit comments

Comments
 (0)