动态规划解法(Java)
状态转移方程:
其中,f[i][j]表示s中的前i个字符与p中的前j个字符是否能够匹配,边界条件为f[0][0] = ture,即两个空字符串是可以匹配的
核心思想: f[i][j]匹配情形分为普通字符匹配("."视为普通字符)和字符+星号组合匹配(视为整体),其中普通字符匹配的子问题只有f[i-1][j-1],即匹配结果取决于字符串s中的前i-1个字符与字符规律p中前j-1个字符是否能够匹配,而字符+星号组合匹配的子问题有两个:f[i-1][j]和f[i][j-2],即匹配结果取决于字符串s中的前i-1个字符与字符规律p中前j个字符是否能够匹配或者将字符+星号组合直接视为空字符。
class Solution {
public boolean isMatch(String s, String p) {
int len_s = s.length();//字符串s的长度
int len_p = p.length();//字符规律p的长度
boolean[][] f = new boolean[len_s + 1][len_p + 1];//表示s中的前i个字符与p中的前j个字符是否能够匹配
f[0][0] = true;//两个空字符串是可以匹配的
for (int i = 0; i <= len_s; i++) {
for (int j = 1; j <= len_p; j++) {
//字符+星号组合匹配
if (p.charAt(j - 1) == '*') {
//星号前字符与字符串s对应字符相匹配
if (matches(s, p, i, j - 1)) {
f[i][j] = f[i - 1][j] || f[i][j - 2];
}
//星号前字符与字符串s对应字符不匹配
else
f[i][j] = f[i][j - 2];
}
//普通字符匹配
else {
if (matches(s, p, i, j)) {
f[i][j] = f[i - 1][j - 1];
}
else
f[i][j] = false;//可省略,f[i][j]默认值为false
}
}
}
return f[len_s][len_p];
}
//matches(x,y) 判断两个字符是否匹配的辅助函数
public boolean matches(String s, String p, int i, int j) {
//s为空字符串,只有字符规律p为空字符串或者全是字符+星号的组合时,才为true
if (i == 0) {
return false;
}
//字符规律p的第j个字符为“.”,可以匹配字符串s的任意单个字符
if (p.charAt(j - 1) == '.') {
return true;
}
//字符串s的第i个字符和字符规律p的第j个字符是否匹配
return s.charAt(i - 1) == p.charAt(j - 1);
}
}