给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
精选题解:
const isMatch = (s, p) => {
if (s == null || p == null) return false;
const sLen = s.length, pLen = p.length;
const dp = new Array(sLen + 1);
for (let i = 0; i < dp.length; i++) {
dp[i] = new Array(pLen + 1).fill(false); // 将项默认为false
}
// base case
dp[0][0] = true;
for (let j = 1; j < pLen + 1; j++) {
if (p[j - 1] == "*") dp[0][j] = dp[0][j - 2];
}
// 迭代
for (let i = 1; i < sLen + 1; i++) {
for (let j = 1; j < pLen + 1; j++) {
if (s[i - 1] == p[j - 1] || p[j - 1] == ".") {
dp[i][j] = dp[i - 1][j - 1];
} else if (p[j - 1] == "*") {
if (s[i - 1] == p[j - 2] || p[j - 2] == ".") {
dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i - 1][j];
} else {
dp[i][j] = dp[i][j - 2];
}
}
}
}
return dp[sLen][pLen]; // 长sLen的s串 是否匹配 长pLen的p串
};
作者:xiao_ben_zhu
链接:https://leetcode-cn.com/problems/regular-expression-matching/solution/shou-hui-tu-jie-wo-tai-nan-liao-by-hyj8/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
个人分析:
以s:aaaa p:a*a 为例
这题使用的是自顶向下分析,自底向上求解
- 自顶向下分析:从后向前进行匹配,相等就各自消掉一个字符,进行子串的匹配,遇到*则判端*前的字符是否相等,不相等就不匹配,相等就按走三条路(1)s啥也不消,p消去a*。(2)s消去一个a,p消去a*。(3)s消去一个a,p啥也不消。其实就是a*是匹配0个,1个还是多个字符的问题。
- 自底向上求解:从一个个小的字串求解,若遇到*,则记录下a*是匹配0个字符,那就和子串dp[i][j - 2] 的结果一样。若匹配1个字符那就和 dp[i - 1][j - 2] 结果一样。若匹配多个那就和子串dp[i - 1][j]的结果一样。