思路
这个问题是一个动态规划问题。我们可以使用动态规划来解决这个问题。首先我们定义一个二维数组dp,其中dp[i][j]表示s的前i个字符和p的前j个字符是否匹配。然后我们根据s和p的字符逐个进行匹配,并更新dp数组。最后,返回dp[m][n],即s和p是否完全匹配。
解题方法
- 初始化一个二维数组dp,大小为(m+1) x (n+1),其中m是s的长度,n是p的长度。
- 初始化dp[0][0]为true,因为空字符串匹配空字符串。
- 对于dp数组的第一行,遍历p的每个字符,如果p[j-1]为'',则dp[0][j]与dp[0][j-1]相同,因为''可以匹配空字符串。
- 遍历s和p的每个字符,填充dp数组:
- 如果s[i-1]和p[j-1]相同,或者p[j-1]为'?',则dp[i][j]取决于dp[i-1][j-1]。
- 如果s[i-1]和p[j-1]不同:
- 如果p[j-1]为'*',则需要检查前面的状态是否为true,如果dp[l][j-1]为true,则dp[i][j]也为true,其中0<=l<=i。
- 否则,dp[i][j]为false。
- 返回dp[m][n],表示s和p是否完全匹配。
复杂度
时间复杂度: O(mn)O(mn)O(mn)
空间复杂度: O(mn)O(mn)O(mn)
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size();
int n = p.size();
vector<vector<bool>> dp(m+1,vector<bool>(n+1,false));
dp[0][0]=true;
for (int j = 1; j <= n; j++)
{
if (p[j - 1] == '*') dp[0][j] = dp[0][j - 1]; // '*' matches empty string
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(s[i-1]==p[j-1])
{
dp[i][j] = dp[i-1][j-1];
}
else
{
if(p[j-1]=='?') dp[i][j] = dp[i-1][j-1];
else if(p[j-1]=='*')
{
if(j==1) dp[i][j] = true;
else
{
for(int l=i;l>=0;l--)
if(dp[l][j-1]==true) dp[i][j] = true;
}
}
else dp[i][j] = false;
}
}
}
return dp[m][n];
}
};
//dp[i][j] 老规矩
//if(s[i]==p[j]||p[j]=='?') dp[i][j] = dp[i-1[j-1]];
//if(s[i]!=p[j])
//if(p[j]=='*')
当 p[j] == '*' 时,状态转移方程为: dp[i][j] = dp[i][j - 1] || dp[i - 1][j - 1] || dp[i - 2][j - 1]......
我们发现 i 是有规律的减小的,因此我们去看看 dp[i - 1][j] :
dp[i - 1][j] = dp[i - 1][j - 1] || dp[i - 2][j - 1] || dp[i - 3][j - 1] ......
我们惊奇的发现, dp[i][j] 的状态转移方程里面除了第一项以外,其余的都可以用 dp[i -1][j] 替代。因此,我们优化我们的状态转移方程为: dp[i][j] = dp[i - 1][j] || dp[i][j - 1] 。
代码可优化为:
class Solution {
public:
bool isMatch(string s, string p) {
int m = s.size();
int n = p.size();
vector<vector<bool>> dp(m+1,vector<bool>(n+1,false));
dp[0][0]=true;
for (int j = 1; j <= n; j++)
{
if (p[j - 1] == '*') dp[0][j] = dp[0][j - 1]; // '*' matches empty string
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(s[i-1]==p[j-1])
{
dp[i][j] = dp[i-1][j-1];
}
else
{
if(p[j-1]=='?') dp[i][j] = dp[i-1][j-1];
else if(p[j-1]=='*')
{
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
}
else dp[i][j] = false;
}
}
}
return dp[m][n];
}
};