- 正则表达式匹配
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
示例 1:
输入:
s = “aa”
p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:
s = “aa”
p = “a*”
输出: true
解释: 因为 ‘*’ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
1.2021年5月22日21:31:35:今天再看,仍是一脸懵逼,收获如下:
1)dp数组扩增一维,应对空字符串
2)难点在于若为*,如何表示多次重复,参照教程
class Solution {
public boolean isMatch(String s, String p) {
if(s == null || p == null) return false;
int len1 = s.length(), len2 = p.length();
boolean dp[][] = new boolean[len1 + 1][len2 + 1];
//若s为空字符串,p不空,但含有*
dp[0][0] = true;
for(int j = 1; j < len2 + 1; j++){
//遍历p字符,其实是从右往左遍历的(不严格)
if(p.charAt(j - 1) == '*') dp[0][j] = dp[0][j - 2];
//若当前为星,此时当做0个处理,则继承前面两位的结果
}
//递推
for(int i = 1; i < len1 + 1; i++){
for(int j = 1; j < len2 + 1; j++){
if(s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.'){
//数组与实际下标相差一,若当前相等,直接继承上一位
dp[i][j] = dp[i - 1][j - 1];
}else if(p.charAt(j - 1) == '*'){
//若不相同,但幸运的是当前p为星
//星号前的字母若与p当前的字母相同,或者星号前的字母为‘.'
if(s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.'){
dp[i][j] = dp[i][j - 2] //*表示0个,由于p当前还没有比对,需要与p前推两个位置比对,所以才是dp[i][j -2]
|| dp[i - 1][j - 2] //表示1个,s.charAt(i - 1) == p.charAt(j - 2)当前相同,双方都向前推一位,
|| dp[i - 1][j]; //表示多个,当前相同,s向前推一位,p保持不变
} else {
dp[i][j] = dp[i][j - 2];
//若不相同,星号表示0为,s不变,p向前推两位
}
}
}
}
return dp[len1][len2];
}
}
2.利用牛客的递推方法:
class Solution {
public boolean isMatch(String s, String p) {
if(s == null || p == null) return false;
char[] str = s.toCharArray();
char[] pattern = p.toCharArray();
return judge(str, 0, pattern, 0);
}
public boolean judge(char[]str, int i, char[] pattern, int j){
int len1 = str.length, len2 = pattern.length;
if(i== len1 && j == len2) return true;
if(i != len1 && j == len2) return false;
//if( i== len1 && j != len2) return false;//注意这样不对,后面可能有*
if(j + 1 < len2 && pattern[j + 1] == '*'){
if(i < len1 && str[i] == pattern[j] || i< len1 && pattern[j] == '.'){
return judge(str, i + 1, pattern, j) || judge(str, i, pattern, j + 2)
|| judge(str, i + 1, pattern, j + 2);//多个, 0个,一个,其中一个可以不写
}else return judge(str, i, pattern, j + 2);
}else if(i < len1 && j < len2 && str[i] == pattern[j] || i < len1 && j < len2 && pattern[j]=='.'){
return judge(str, i+ 1, pattern, j+1);
}
return false;
}
}