18.正则表达式匹配
请实现一个函数用来匹配包括'.'和'*'的正则表达式。
模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。
在本题中,匹配是指字符串的所有字符匹配整个模式。
例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。
数据范围:
输入字符串长度 [0,300]。
样例:
输入:
s="aa"
p="a*"
输出:
true
代码:
class Solution {
public boolean isMatch(String s, String p) {
//m为字符串s的长度,n为字符串p的长度
int m = s.length(), n = p.length();
// dp[i][j] 表示s[i..m-1]和p[j..n-1]是否匹配
boolean[][] dp = new boolean[m + 1][n + 1];
// 空字符串匹配空模式
dp[m][n] = true;
// 从后往前处理
// i从m开始表示处理s的子串是空字符串,因为模式p可能包含像a*这样的模式,它可以匹配空字符串
for (int i = m; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
// 检查当前第一个字符是否匹配:
// i不能超出字符串长度
// 字符相等或者模式为'.'(可以匹配任意字符)
boolean firstMatch = i < m && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.');
// 处理'*'情况
if (j + 1 < n && p.charAt(j + 1) == '*') {
// 两种情况满足任意一种即可:
// 匹配0次:跳过当前字符和'*'(即j+2)
// 匹配1次:当前字符匹配成功,然后继续用*匹配剩下的字符串(i+1)
dp[i][j] = dp[i][j + 2] || (firstMatch && dp[i + 1][j]);
} else {
// 普通字符匹配:当前字符匹配成功,且剩下的也匹配成功
dp[i][j] = firstMatch && dp[i + 1][j + 1];
}
}
}
//最终结果是整个字符串和整个模式串是否匹配
return dp[0][0];
}
}