题目大意:给以一个字符串s和一个模式串p,其实模式串中*表示任意长的字符,? 表示任意单个字符。
解题思路:动态规划。
用dp[i][j]表示 p的前i个字符和s的前j个字符是否匹配。
当p[i] != '*' 时,若p[i] == s[j]或者p[i] == '?' 是 dp[i][j] = dp[i - 1][j - 1], 否则dp[i][j] = false;
当p[i] == '*'时,找到dp[i - 1][m]为true的m下标,将m后面的所有dp[i][j] = true, j > m
初始化dp.
dp[0][0] = true,表示两个空字符串比较,自然匹配
dp[i][0] = dp[i - 1][0] && p[i] == '*'
dp[0][i] = false;
这题用二维数组会空间不够,所以压缩为一维空间,c++代码有个用例超时过不了,改为java代码可以通过。
public class Solution {
public boolean isMatch(String s, String p) {
if(s == null && p == null) {
return true;
} else if(s == null) {
return false;
} else if(p == null) {
return false;
}
int num = 0;
for(int i = 0; i < p.length(); i++) {
if(p.charAt(i) != '*') {
num++;
}
}
if(num > s.length()) {
return false;
}
boolean dp[] = new boolean[s.length() + 1];
dp[0] = true;
for(int i = 1; i <= p.length(); i++) {
if(p.charAt(i - 1) != '*') {
for(int j = s.length(); j >= 1; j--) { // 逆向,为了取得上次的结果
dp[j] = dp[j - 1] && (p.charAt(i - 1) == s.charAt(j - 1) || p.charAt(i - 1) == '?');
}
} else {
int j = 0;
while(j <= s.length() && !dp[j]) {
j++;
}
for(; j <= s.length(); j++) {
dp[j] = true;
}
}
dp[0] = dp[0] && (p.charAt(i - 1) == '*');
}
return dp[s.length()];
}
}