Skip to content

Commit 219c9f1

Browse files
committed
10.正则表达式匹配,动态规划
1 parent ef7dcb0 commit 219c9f1

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

leetcode_Java/DoneTitle.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
4. 寻找两个有序数组的中位数
55
5. 最长回文子串
66
8. 字符串转换整数 (atoi)
7+
10. 正则表达式匹配
78
11. 盛最多水的容器
89
15. 三数之和
910
17. 电话号码的字母组合

leetcode_Java/DoneType.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555

5656
三、动态规划
5757
5. 最长回文子串
58+
10. 正则表达式匹配
5859
22. 括号生成
5960
32. 最长有效括号
6061
42. 接雨水

leetcode_Java/Solution0010.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// 10. 正则表达式匹配
2+
3+
4+
/*
5+
1、定义dp数组:dp[i][j] 表示 s 的前 i 个字符是否能被 p 的前 j 个字符匹配
6+
2、初始化
7+
1)s为空,p为空,能匹配
8+
2)p为空,s不为空,不能匹配。boolean数组默认值为false,无需处理
9+
3)s为空,p不为空,由于*可以匹配0个字符,所以可能匹配
10+
3、状态转移方程
11+
1)s[i]是{字母},p[j]是{字母,点,星}
12+
2)s[i]字母 与 p[j]字母:两者相等则dp[i][j]看前一项即可,所以dp[i][j] = dp[i-1][j-1]。两者不等则不能匹配
13+
3)s[i]字母 与 p[j]点:点能配任何一个字母,所以两者必然相等,所以dp[i][j]看前一项即可,所以dp[i][j] = dp[i-1][j-1]
14+
4)s[i]字母 与 p[j]星:星代表零个或多个前面的那一个元素
15+
① 若为0个,匹配0次的情况,则代表删掉了p[j-1]和p[j],所以此时dp[i][j] = dp[i][j-2]
16+
③ 若为多个,匹配1次或多次的情况,如果s[i] == p[j-1] || p[j-1] == '.',即s的末尾字符与p的末尾前一字符匹配,
17+
那么可以忽略s的末尾字符,因为p的末尾可以匹配1个或多个,此时dp[i][j] = dp[i-1][j]
18+
4、遍历dp数组填表:第一个for循环遍历字符串s,第二个for循环遍历字符串p
19+
5、返回结果:最后一个状态就是结果
20+
21+
======== 3-2 =========
22+
s = "abc", p = "abc"
23+
↑ ↑
24+
i j
25+
======== 3-3 =========
26+
s = "abc", p = "ab."
27+
↑ ↑
28+
i j
29+
======== 3-4-1 =======
30+
s = "a", p = "ab*"
31+
↑ ↑
32+
i j
33+
======== 3-4-2 =======
34+
s = "acc", p = "ac*"
35+
↑ ↑
36+
i j
37+
s = "acc", p = "ac*"
38+
↑ ↑
39+
i j
40+
s = "acc", p = "ac*"
41+
↑ ↑
42+
i j
43+
======== 3-4-2 =======
44+
s = "acc", p = "a.*"
45+
↑ ↑
46+
i j
47+
*/
48+
class Solution {
49+
public boolean isMatch(String s, String p) {
50+
if (s == null || p == null) {
51+
return false;
52+
}
53+
int m = s.length(), n = p.length();
54+
boolean[][] dp = new boolean[m + 1][n + 1];
55+
dp[0][0] = true;
56+
for (int i = 2; i <= n; i += 2) {
57+
if (p.charAt(i - 1) == '*') {
58+
dp[0][i] = dp[0][i - 2];
59+
}
60+
}
61+
for (int i = 1; i <= m; i++) {
62+
for (int j = 1; j <= n; j++) {
63+
char sc = s.charAt(i - 1);
64+
char pc = p.charAt(j - 1);
65+
char pcPre = p.charAt(j - 2);
66+
if (sc == pc || pc == '.') {
67+
dp[i][j] = dp[i - 1][j - 1];
68+
} else if (pc == '*') {
69+
if (dp[i][j - 2]) {
70+
dp[i][j] = true;
71+
} else if (sc == pcPre || pcPre == '.') {
72+
dp[i][j] = dp[i - 1][j];
73+
}
74+
}
75+
}
76+
}
77+
return dp[m][n];
78+
}
79+
}

0 commit comments

Comments
 (0)