/**
* Index: 44
* Title: Wildcard Matching
* Author: ltree98
**/
题意
字符串匹配
Note:
- ‘?’ 可匹配任意一个字符(且必须匹配一个字符)
- ‘*’ 可匹配任意长度字符(包括空串)
我的
思路
动态规划,
二维数组,以s串为行,p串为列;
dp[i][j] 表示 0i的s串能否与0j的p串匹配成功。
推倒公式为:
- p[j]为 ‘*’,dp[i][j] = dp[i-1][j-1] || dp[i][j-1] || dp[i-1][j]
- p[j]为 ‘?’,dp[i][j] = dp[i-1][j-1] && true
- p[j]为 ‘a’~‘z’,dp[i][j] = dp[i-1][j-1] && (s[i] == p[j])
注意处理空串输入情况。
时间复杂度:O(m * n)
空间复杂度:O(m * n)
实现
class Solution {
public:
bool isMatch(string s, string p) {
if(p.empty())
return s.empty();
vector<vector<bool>> dp(s.length()+1, vector<bool>(p.length()+1, false));
dp[0][0] = true;
for(int i = 1; i <= p.length(); i++) {
if(p[i-1] != '*')
break;
dp[0][i] = true;
}
for(int i = 1; i <= s.length(); i++) {
for(int j = 1; j <= p.length(); j++) {
if(p[j-1] == '*') {
dp[i][j] = dp[i-1][j-1] || dp[i][j-1] || dp[i-1][j];
}
else if(p[j-1] == '?') {
dp[i][j] = dp[i-1][j-1];
}
else {
dp[i][j] = dp[i-1][j-1] && s[i-1] == p[j-1];
}
}
}
return dp[s.length()][p.length()];
}
};
进阶
思路
深度优先搜索
有减枝,所以时间可以小于 O(m * n)
实现
C++版本,作者:Hanafubuki
class Solution {
// return value:
// 0: reach the end of s but unmatched
// 1: unmatched without reaching the end of s
// 2: matched
int dfs(string& s, string& p, int si, int pi) {
if (si == s.size() and pi == p.size()) return 2;
if (si == s.size() and p[pi] != '*') return 0;
if (pi == p.size()) return 1;
if (p[pi] == '*') {
if (pi+1 < p.size() and p[pi+1] == '*')
return dfs(s, p, si, pi+1); // skip duplicate '*'
for(int i = 0; i <= s.size()-si; ++i) {
int ret = dfs(s, p, si+i, pi+1);
if (ret == 0 or ret == 2) return ret;
}
}
if (p[pi] == '?' or s[si] == p[pi])
return dfs(s, p, si+1, pi+1);
return 1;
}
public:
bool isMatch(string s, string p) {
return dfs(s, p, 0, 0) > 1;
}
};