题目来源: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);
}
该博客讨论了如何解决LeetCode上的正则表达式匹配问题。通过动态规划方法,判断一个字符串是否能被给定的包含特殊字符*.的模式串匹配。关键在于处理*的匹配情况,分为匹配字符和不匹配字符两种情况。代码中定义了match函数来检查单个字符是否匹配,并在主函数中构建了二维动态规划数组进行匹配状态转移。
2398

被折叠的 条评论
为什么被折叠?



