题目:10. 正则表达式匹配
思路:动态规划
- 若
s[i] == p[j]
,或者p[j] == '.'
,那么s[i]
与p[j]
匹配,转移方程:dp[i][j] = dp[i - 1][j - 1]
- 若
s[i] != p[j]
,并且p[j] == '*'
,此时,p往前看一位:s[i] != p[j-1]
,表示s[i]无法与*前的字母匹配,因此dp[i][j] = dp[i][j - 2]
s[i] == p[j-1]
,此时分3种情况:
(1)s[i]
与p[j-1]
匹配,dp[i][j] = dp[i][j - 1]
;
(2)s[i-1]
与p[j]
可以匹配,那么再来一个*
前的字母s[i]
也可以匹配成功,dp[i][j] = dp[i - 1][j]
;
(3)*
表示0个,s[i]
直接和p[j-2]
匹配,dp[i][j] = dp[i][j - 2]
。三种情况取或即可。
- 若
s[i]
和p[j]
都是字母且不相等,无法匹配,dp[i][j] = false
初始化:
dp[0][0] = true
- 若
p[j] == '*'
,j== 0
或j==1
,dp[0][j] = true
- 若
p[j] == '*'
,j > 2
,dp[0][j] = dp[0][j-2]
- 其余情况
dp[0][j] = false
代码:
class Solution {
public boolean isMatch(String s, String p) {
int lens = s.length();
int lenp = p.length();
boolean[][] dp = new boolean[lens + 1][lenp + 1];
// init
dp[0][0] = true;
for (int j = 1; j <= lenp; j++) {
if (p.charAt(j-1) == '*') {
if (j-2 > 0) {
dp[0][j] = dp[0][j-2];
}
else {
dp[0][j] = true;
}
}
else {
dp[0][j] = false;
}
}
for (int i = 1; i <= lens; i++) {
for (int j = 1; j <= lenp; j++) {
if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.') {
dp[i][j] = dp[i - 1][j - 1];
}
else {
if (p.charAt(j - 1) == '*') {
if (j - 2 >= 0 && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.')) {
dp[i][j] = dp[i][j - 1] || dp[i - 1][j] || dp[i][j - 2];
}
else if (j - 2 >= 0 && s.charAt(i - 1) != p.charAt(j - 2)) {
dp[i][j] = dp[i][j - 2];
}
}
else {
dp[i][j] = false;
}
}
}
}
return dp[lens][lenp];
}
}