给定一个字符串s和一个字符规律p,写一个支持‘.’和‘’的正则表达式匹配。
‘.’匹配任意单个字符
‘’匹配零个or多个前面的那一个元素
所谓匹配,是要涵盖整个字符串s,而不是部分字符串。
s = aa p = a false
s = aa p = a* true
s = ab p = .* true
思路:动态规划法,就是找到状态转移方程和边界条件。考虑全面很难,没做过类似的问题根本做不出来。另:只要是动态规划法,一般都能对空间复杂度做优化,本题也行。
然后直接看代码:(未优化空间复杂度)
class Solution {
public boolean isMatch(String s, String p) {
int sLength = s.length();
int pLength = p.length();
boolean[][] dp = new boolean[sLength + 1][pLength + 1]; // 未赋值默认false
dp[0][0] = true; // 一定满足
for (int i = 0; i <= sLength; i++) { // s从第0个字符开始
for (int j = 1; j <= pLength; j++) { // p从第1个字符开始
if (p.charAt(j - 1) == '*') {
dp[i][j] = dp[i][j - 2]; // p去掉 字符 + * 后,直接用之前的结果赋值
if (matchChar(s, p, i, j - 1)) { //p去掉 * 后,考察匹配情况
dp[i][j] = dp[i][j] || dp[i - 1][j]; // 只要一种能成功匹配就行
}
} else {
if (matchChar(s, p, i, j)) { // 考察匹配情况
dp[i][j] = dp[i - 1][j - 1];
}
}
}
}
return dp[sLength][pLength]; //最后结果
}
public boolean matchChar(String s, String p, int sPos, int pPos) {
if (sPos == 0) { // 串为空串时,不匹配
return false;
}
if (p.charAt(pPos - 1) == '.' || s.charAt(sPos - 1) == p.charAt(pPos - 1)) {
return true;
} else {
return false;
}
}
}