leetcode 10. Regular Expression Matching
Given an input string (s) and a pattern §, implement regular expression matching with support for ‘.’ and ‘*’.
‘.’ Matches any single character.
‘*’ Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Note:
s could be empty and contains only lowercase letters a-z.
p could be empty and contains only lowercase letters a-z, and characters like . or *.
Example 1:
Input:
s = “aa”
p = “a”
Output: false
Explanation: “a” does not match the entire string “aa”.
Example 2:
Input:
s = “aa”
p = “a*”
Output: true
Explanation: ‘*’ means zero or more of the preceding element, ‘a’. Therefore, by repeating ‘a’ once, it becomes “aa”.
Example 3:
Input:
s = “ab”
p = “."
Output: true
Explanation: ".” means “zero or more (*) of any character (.)”.
Example 4:
Input:
s = “aab”
p = “cab”
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches “aab”.
Example 5:
Input:
s = “mississippi”
p = “misisp*.”
Output: false
这个题用 DP 写,主要难点在于状态转移的确定以及初始值的确定。为了方便处理,统一在 s,p
前面加一个特殊字符,比如 #
,令 表示 和 匹配与否,则 (因为 0 处都是特殊字符 #
) ,另外的初始化是:
然后是状态转移:
s[i]==p[j]||p[j]=='.'
,则有dp[i][j]=dp[i-1][j-1]
p[j]=='*'
,p[j-1]!=s[i]&&p[j-1]!='.'
则'*'
作用必须是0:dp[i][j]=dp[i][j-2]
dp[i][j]=dp[i][j-2]||dp[i][j-1]||dp[i-1][j]
分别表示*
重复0、1、多次的情况
时间复杂度: (分别是主串与匹配串的长度)
class Solution {
public:
bool dp[1000][1000];
bool isMatch(string s, string p) {
int slen=s.length(),plen=p.length();
memset(dp,false,sizeof(dp));
s="#"+s;p="#"+p;
dp[0][0]=true;
for(int j=1;j<=plen;j++)
if(p[j]=='*'&&dp[0][j-2])
dp[0][j]=true;
for(int i=1;i<=slen;i++)
for(int j=1;j<=plen;j++){
if(s[i]==p[j]||p[j]=='.')dp[i][j]=dp[i-1][j-1];
if(p[j]=='*'){
if(p[j-1]!=s[i]&&p[j-1]!='.')
dp[i][j]=dp[i][j-2];
else
dp[i][j]=dp[i][j-2]||dp[i][j-1]||dp[i-1][j];
}
}
return dp[slen][plen];
}
};