您的位置:首页 > 其它

leetcode 10 Regular Expression Matching

2016-04-10 11:33 429 查看

问题

https://leetcode.com/problems/regular-expression-matching/

方法一 回溯(24ms)

class Solution {
public:
bool sol(const char *s, const char * p)
{
if (*p == 0)
return *s==0;

if (*(p+1) == '*')
{
while(1) // ?* 先匹配0个或多个,然后递归
{
if (sol(s, p+2))
return true;
if (*s && (*s == *p || *p =='.'))
s++;
else
break;
}
return false;  // 当 ?* 不能匹配时 说明不满足
}else{
return (*s &&(*s == *p || *p =='.')) && sol(s+1, p+1);
}
}
bool isMatch(string s, string p) {
return sol(s.c_str(), p.c_str());
}
};


注意按照p分情况讨论,p+1为* 时,依次判断0~n次。

最坏复杂度分析:

最坏情况举例 p = “.*.*.*.*.*x “, s = “abcdefgh”

复杂度为len(p) = m (.* 看做一个), len(s) = n

O(nm)

方法二 dp (4ms)

class Solution {
public:
bool isMatch(string s, string p) {
bool dp[2][p.size() + 1];
memset(dp, 0, sizeof(dp));
int cur = 0;
dp[cur][0] = true;

for (int i=0; i< p.size(); i++)
if (p[i]== '*')
dp[cur][i+1] = dp[cur][i] = dp[cur][i-1];

for (int i=0; i< s.size(); i++)
{
cur = !cur;
dp[cur][0] = false;
for (int j= 0; j< p.size(); j++)
{
if (p[j]!= '*')
{
if (j+1 <p.size() && p[j+1]=='*')
{
dp[cur][j+1] = dp[cur][j] || ((dp[!cur][j] || dp[!cur][j+1]) && (p[j]=='.'||s[i]==p[j]));
}
else
dp[cur][j+1] = dp[!cur][j] && (p[j]=='.' || s[i]==p[j]);
}else{
dp[cur][j+1] = dp[cur][j] ;
}
}
}

return dp[cur][p.size()];
}
};


将s中的每个字符看做一个阶段,定义状态f(i, j) 为原串s的0~i个字符与模式串p的 0~j 个字符是否匹配。

状态转移方程:

如果p[j+1 ] != ‘*’ f(i, j) = f(i-1, j-1) && p[j] == s[i];

如果p[j+1] == ‘*’ f(i, j) = f(i, j-1) 《 匹配0个》 | f(i-1, j-1) && p[j] == s[i] 《 匹配1个》| f(i-1, j) && p[j] == s[i] 《匹配>= 2个》;

如果p[j] = ‘*’ f(i, j) = f(i, j-1);

初始状态: f(-1, -1) = true;

如果p[j] = ‘*’ f(-1, j) = f(-1, j-1) = f(-1, j-2) //注意不要忘记;

复杂度为len(p) = m, len(s) = n;

空间复杂度2m;

时间复杂度m*n;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode