题目链接:Regular Expression Matching
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).
The function prototype should be:
bool isMatch(const char *s, const char *p)
Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true
这道题的要求是判断字符串s能否和正则表达式p相匹配。其中’.’匹配任意单个字符,’*‘匹配0个或多个’*‘的前一字符。如果匹配能整个串返回true。
-
回溯暴力匹配
思路是进行递归回溯匹配。当p的下一个字符是’*‘的时候,则循环检测p与s的当前字符是否匹配(每次s后移1位,直到结束或者不匹配);当p的下一个字符不是’*‘的时候,直接检测字符串是否结束或者p与s的当前字符是否匹配。注意’.’可以与任意单个字符匹配。
时间复杂度:???
空间复杂度:O(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution
{
public:
bool isMatch(const char *s, const char *p)
{
if(*p == '\0' )
return *s == '\0';
if(*(p + 1) == '*')
{
while(*s != '\0' && (*p == '.' || *s == *p))
{
if(isMatch(s, p + 2))
return true;
++ s;
}
return isMatch(s, p + 2);
}
else if(*s != '\0' && (*p == '.' || *s == *p))
return isMatch(s + 1, p + 1);
return false;
}
};
-
动态规划
思路是使用bool类型的二维数组dp[m+1][n+1](m、n分别为字符串s和p的长度)记录s和p是否匹配,即dp[i+1][j+1]表示s的前i个字符是否与p的前j的字符相匹配。
如果p[j]不等于’*‘,则dp[i + 1][j + 1] = dp[i][j] && s[i] == p[j]
如果p[j]等于’*‘,则当且仅当在下面三种情况为真,dp[i + 1][j + 1]为真:
-
’*‘前面字符重复出现0次,则p字符串需要往前看2位,即dp[i + 1][j - 1]是否为真
-
’*‘前面的字符重复出现1次,则p字符串只需要往前看1位,即dp[i + 1][j]是否为真
-
’*‘前面的字符重复出现次数大于1次,则s字符串需要往前看1位,即dp[i][j + 1]是否为真,以及s字符串当前字符(s[i])与p字符串’*‘前面字符(p[j - 1])是否相匹配。
注意,’.’可以与任意单个字符匹配。
注:动态规划思路是参考的这里。这里将空间复杂度降低到了O(n),有兴趣的可以看看。
时间复杂度:O(mn)
空间复杂度:O(mn)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution
{
public:
bool isMatch(const char *s, const char *p)
{
int m = strlen(s), n = strlen(p);
bool dp[m + 1][n + 1];
dp[0][0] = true;
for(int i = 0; i < m; ++ i)
dp[i + 1][0] = false;
for(int j = 0; j < n; ++ j)
dp[0][j + 1] = '*' == p[j] && dp[0][j - 1];
for(int i = 0; i < m; ++ i)
for(int j = 0; j < n; ++ j)
{
if(p[j] != '*')
dp[i + 1][j + 1] = dp[i][j] && ('.' == p[j] || s[i] == p[j]);
else
dp[i + 1][j + 1] = dp[i + 1][j - 1] || dp[i + 1][j] ||
dp[i][j + 1] && ('.' == p[j - 1] || s[i] == p[j - 1]);
}
return dp[m][n];
}
};