题目来源:https://leetcode.cn/problems/regular-expression-matching/
大致题意:
给一个字符串 s 和正则模式串 p,判断模式串能否匹配到字符串 s
其中模式串由小写字符和特殊字符 * 和 . 组成:
- . 可以匹配任意字符
- * 可以匹配 0 - 任意多个前一个字符
思路
使用 dp[i][j] 表示 s[0, i] 和 p[0, j] 是否匹配,那么:
- 若 s[i] 与 p[j] 不相等,则 dp[i][j] 为 false
- 若 p[j] 为 . 或 s[i] 与 p[j] 相等,则 dp[i][j] = dp[i - 1][j - 1]
- 若 p[j] 为 *,则取决于当前 * 匹配多少个字符
- 首先,需要判断 s[i] 与 p[j - 1] 是否匹配,若不匹配,那么表示 * 不能匹配字符,即 dp[i][j] = dp[i][j - 2]
2.如果 s[i] 与 p[j - 1] 匹配成功,那么 * 可以匹配任意多个字符 s[i],则 dp[i][j] = dp[i - 1][j] | dp[i][j - 2]
代码:
public boolean isMatch(String s, String p) {
int m = s.length();
int n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true;
for (int i = 0; i <= m; i++) {
for (int j = 1; j <= n; j++) {
// 若当前模式串处字符为 *
if (p.charAt(j - 1) == '*') {
// 首先判断 s[i - 1] 是否与 p[j - 2] 匹配
if (match(s, p, i, j - 1)) {
// 若匹配成功,* 可以匹配任意个 s[i - 1]
dp[i][j] = dp[i - 1][j] || dp[i][j - 2];
} else {
// 匹配失败,* 不能匹配字符
dp[i][j] = dp[i][j - 2];
}
} else {
// 判断 s[i - 1] 是否与 p[j - 2] 匹配
if (match(s, p, i, j)) {
dp[i][j] = dp[i - 1][j - 1];
}
}
}
}
return dp[m][n];
}
/**
* 判断 s[i - 1] 与 p[j - 1] 是否匹配
* @param s
* @param p
* @param i
* @param j
* @return
*/
public boolean match(String s, String p, int i, int j) {
if (i == 0) {
return false;
}
// 若当前为通配符,直接返回
if (p.charAt(j - 1) == '.') {
return true;
}
return s.charAt(i - 1) == p.charAt(j - 1);
}