您的位置:首页 > 其它

Leetcode 44. Wildcard Matching

2016-04-25 10:54 429 查看

问题

https://leetcode.com/problems/wildcard-matching/

解法一(DP)

时间复杂度
4000
O(n*m) 空间复杂度 2∗m与正则匹配dp实现相同

参考:

http://blog.csdn.net/galaxy_wolf/article/details/51111906

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=1; i<=p.size(); ++i)
if (p[i-1] == '*')
dp[cur][i] = dp[cur][i-1];
for (int i=0; i<s.size(); ++i)
{
dp[!cur][0] = 0;
for (int j=1; j<=p.size(); ++j)
{
if (p[j-1]=='*')
{               // 0                1               multi
dp[!cur][j] = dp[!cur][j-1] | (dp[cur][j-1]) | dp[cur][j];
}else{
if (dp[cur][j-1] && (p[j-1] == '?' || p[j-1] ==s[i]))
dp[!cur][j] = true;
else
dp[!cur][j] = false;
}
}
cur = !cur;
}
return dp[cur][p.size()];
}
};


解法二(回溯)

由于本题中只会有一种变长匹配”*”, 在出现”*”处我们都要枚举 “*” 匹配0~多个,的情况,如果之后不匹配则要回到”*” 处。如果p中存在多个”*”我们只需要在最后一个出现的”*” 处进行回溯,这是因为如下面的例子:

s:cabcefabcd

p:c*abc*d

此时有两种匹配方案, 第一个* 匹配0个字符第二个* 匹配5个字符

第二种方案, 第一个* 匹配5个字符第二个* 匹配0个字符

如果将*abc* 看做一个整体,那么在要让*abc与s中某一段相匹配,在后一个* 处枚举匹配0~多个,就可以将*abc* 能够匹配的所有情况列举出来。

因此时间复杂度为 o(n*m), 空间复杂度O(1)

而在正则匹配中由于存在多个可变长的匹配项,我们必须在每个可变长匹配项处回溯:



s:aaaccc

p:a*c*accc

此时必须枚举到a* 匹配2个a, c* 不匹配才能得到s与p匹配。

class Solution {
public:
bool isMatch(string s, string p) {
int star = -1;
int ss = 0;
int i =0;
int j= 0;
while(i< s.size())
{
if (j <p.size() && p[j]=='?' || p[j] ==s[i])
{
++i; ++j;
}else if (j< p.size() && p[j] == '*')
{
star = j+1;// next
ss = i; //0
j = star;
}else if (star >= 0)
{
j = star;
i = ++ss;// 1...mulit
}else
{
return false;
}
}
while(j<p.size() && p[j]=='*') ++j;
if (i==s.size()&& j==p.size())
return true;
return false;
}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: