题目描述
// 力扣
// 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则
// 表达式匹配。
// '.' 匹配任意单个字符
// '*' 匹配零个或多个前面的那一个元素
// 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
题解
// 本题与剑指offer 19题相同。
// 递归法
class Solution {
public boolean isMatch(String s, String p) {
if (s == null || p == null)
return false;
int si = 0;
int pi = 0;
return isMatch(s, p, 0, 0);
}
private boolean isMatch(String s, String p, int si, int pi) {
if (pi == p.length() && si == s.length())
return true;
if (si < s.length() && pi == p.length())
return false;
if (pi + 1 < p.length() && p.charAt(pi + 1) == '*') {
if ((si < s.length() && s.charAt(si) == p.charAt(pi)) || (si < s.length() && p.charAt(pi) == '.')) {
return isMatch(s, p, si, pi + 2) ||
isMatch(s, p, si + 1, pi + 2) ||
isMatch(s, p, si + 1, pi);
}
else {
return isMatch(s, p, si, pi + 2);
}
}
else {
if ((si < s.length() && s.charAt(si) == p.charAt(pi)) || (si < s.length() && p.charAt(pi) == '.'))
return isMatch(s, p, si + 1, pi + 1);
}
return false;
}
}
// 动态规划
// 最优解
// 执行用时:4 ms, 在所有 Java 提交中击败了80.70%的用户
// 内存消耗:38.5 M, 在所有 Java 提交中击败了27.63%的用户
class Solution {
public boolean isMatch(String s, String p) {
if (s == null || p == null)
return false;
char[] str = s.toCharArray();
char[] pattern = p.toCharArray();
int slen = str.length;
int plen = pattern.length;
boolean[][] dp = new boolean[slen + 1][plen + 1];
dp[0][0] = true;
for (int i = 1; i <= plen; i++) {
if (pattern[i - 1] == '*')
dp[0][i] = dp[0][i - 2];
}
for (int i = 1; i <= slen; i++) {
for (int j = 1; j <= plen; j++) {
if (str[i - 1] == pattern[j - 1] || pattern[j - 1] == '.') {
dp[i][j] = dp[i - 1][j - 1];
}
else if (pattern[j - 1] == '*') {
if (pattern[j - 2] == str[i - 1] || pattern[j - 2] == '.') {
dp[i][j] |= dp[i][j - 1];
dp[i][j] |= dp[i - 1][j];
dp[i][j] |= dp[i][j - 2];
}
else {
dp[i][j] = dp[i][j - 2];
}
}
}
}
return dp[slen][plen];
}
}