动态规划你杀了我吧给你一个字符串
s
和一个字符规律p
,请你来实现一个支持'.'
和'*'
的正则表达式匹配。
'.'
匹配任意单个字符'*'
匹配零个或多个前面的那一个元素所谓匹配,是要涵盖 整个 字符串
s
的,而不是部分字符串。示例 1:
输入:s = "aa" p = "a" 输出:false 解释:"a" 无法匹配 "aa" 整个字符串。示例 2:
输入:s = "aa" p = "a*" 输出:true 解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。示例 3:
输入:s = "ab" p = ".*" 输出:true 解释:".*" 表示可匹配零个或多个('*')任意字符('.')。示例 4:
输入:s = "aab" p = "c*a*b" 输出:true 解释:因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。示例 5:
输入:s = "mississippi" p = "mis*is*p*." 输出:false提示:
0 <= s.length <= 20
0 <= p.length <= 30
s
可能为空,且只包含从a-z
的小写字母。p
可能为空,且只包含从a-z
的小写字母,以及字符.
和*
。- 保证每次出现字符
*
时,前面都匹配到有效的字符
/**
动态规划
dp[i][j] s[i]之前与p[j]之前的匹配情况
空字符串:两者为空则匹配即dp[0][0]匹配
p字符串为空的话则除s为空外不匹配
s字符串为空还需要讨论,比如“.*”等情况
dp[i][j]={
if(p[j]!='*'){
dp[i-1][j-1],match(s[i],p[j])
false,!match(s[i],p[j])
}else{
dp[i-1][j]|dp[i][j-2],match(s[i],p[j-1])//丢掉星号组合或者丢掉匹配的s
dp[i][j-2],!match(s[i],p[j-1])//丢掉星号组合
}
}
match(s[i],p[j]){
i==-1 false
p[j]=='.' true
s[i]==p[j] true
otherwise false
}
**/
class Solution {
public boolean isMatch(String s, String p) {
int sl=s.length(),pl=p.length();
boolean[][] dp=new boolean[sl+1][pl+1];
char[] ss=s.toCharArray();
char[] pp=p.toCharArray();
for(int i=0;i<=sl;i++) {
for(int j=0;j<=pl;j++) {
if(j==0) {
dp[i][j]=i==0;
}else {
if(pp[j-1]!='*') {
if(match(ss,pp,i,j)) {
dp[i][j]=dp[i-1][j-1];
}
}else {
dp[i][j]=dp[i][j-2];
if(match(ss,pp,i,j-1)) {
dp[i][j]|=dp[i-1][j];
}
}
}
}
}
return dp[sl][pl];
}
public boolean match(char[] s,char[] p,int i,int j){
if(i==0)return false;//空字符串不匹配
if(p[j-1]=='.')return true;
return s[i-1]==p[j-1];
}
}